diff --git a/tree/Makefile b/tree/Makefile deleted file mode 100644 index d94efb98..00000000 --- a/tree/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -all: - @g++ main.cpp -o depTree - @echo "Running dummy depTree..." - @./depTree -clean: - rm -f depTree diff --git a/tree/main.cpp b/tree/main.cpp deleted file mode 100644 index fe238bfd..00000000 --- a/tree/main.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include -#include - -#include "tree.hh" - -using namespace std; - -class Package -{ - public: - Package( string name ) { this->name = name; }; - ~Package() {}; - string getName() { return this->name; }; - private: - string name; -}; - -typedef tree Tree; - -int main(int argc, char *argv[]) -{ - vector dependencies; - - Package *kdebase = new Package("kdebase"); - Package *kdelibs = new Package("kdelibs"); - Package *kdeartwork = new Package("kdeartwork"); - Package *kdepim = new Package("kdepim"); - Package *glibc = new Package("glibc"); - Package *gcc = new Package("gcc"); - Package *xorg = new Package("xorg-x11"); - - Tree depTree; - Tree::iterator top, element; - - top = depTree.begin(); - - /* - * kde_ - * |_kdebase_ - * | |_kdelibs - * | |_kdeartwork_ - * | | - * | |_xorg-x11_ - * | |_glibc - * | |_gcc - * | - * |_kdepim_ - * |_xorg-x11_ - * |_glibc - * |_gcc - */ - - element = depTree.insert( top, *kdebase ); - depTree.append_child( element, *kdelibs ); - element = depTree.append_child( element, *kdeartwork ); - element = depTree.append_child( element, *xorg ); - depTree.append_child( element, *glibc ); - depTree.append_child( element, *gcc ); - element = depTree.insert( top, *kdepim ); - element = depTree.append_child( element, *xorg ); - depTree.append_child( element, *glibc ); - depTree.append_child( element, *gcc ); - - cout << "...Tracked Dependencies..." << endl; - - Tree::post_order_iterator sib_post = depTree.begin_post(); - while( sib_post != depTree.end_post() ) - { - vector::iterator p = find( dependencies.begin(), dependencies.end(), sib_post->getName() ); - - if( p == dependencies.end() ) - dependencies.push_back( sib_post->getName() ); - - ++sib_post; - } - - for( int i = 0; i < dependencies.size(); i++ ) - cout << dependencies[i] << endl; - - return 0; -} diff --git a/tree/tree.hh b/tree/tree.hh deleted file mode 100644 index 0d139204..00000000 --- a/tree/tree.hh +++ /dev/null @@ -1,2029 +0,0 @@ -/* - - $Id: tree.hh,v 1.117 2004/11/07 18:23:41 kp229 Exp $ - - STL-like templated tree class. - Copyright (C) 2001 Kasper Peeters - - See - - http://www.damtp.cam.ac.uk/user/kp229/tree/ - - for more information and documentation. See the Changelog file for - other credits. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - TODO: - 'Move' members are long overdue; will hopefully be incorporated in the - next release. - - Fixed depth iterators do not iterate over the entire range if there - are 'holes' in the tree. - - If a range uses const iter_base& as end iterator, things will - inevitably go wrong, because upcast from iter_base to a non-sibling_iter - is incorrect. This upcast should be removed (and then all illegal uses - as previously in 'equal' will be flagged by the compiler). This requires - new copy constructors though. - - There's a bug in replace(sibling_iterator, ...) when the ranges - sit next to each other. Turned up in append_child(iter,iter) - but has been avoided now. - - "std::operator<" does not work correctly on our iterators, and for some - reason a globally defined template operator< did not get picked up. - Using a comparison class now, but this should be investigated. -*/ - -#ifndef tree_hh_ -#define tree_hh_ - -#include -#include -#include -#include -#include - -// HP-style construct/destroy have gone from the standard, -// so here is a copy. - -namespace kp { - -template -void constructor(T1* p, T2& val) - { - new ((void *) p) T1(val); - } - -template -void constructor(T1* p) - { - new ((void *) p) T1; - } - -template -void destructor(T1* p) - { - p->~T1(); - } - -}; - -template -class tree_node_ { // size: 5*4=20 bytes (on 32 bit arch), can be reduced by 8. - public: - tree_node_ *parent; - tree_node_ *first_child, *last_child; - tree_node_ *prev_sibling, *next_sibling; - T data; -}; - -template > > -class tree { - protected: - typedef tree_node_ tree_node; - public: - typedef T value_type; - - class iterator_base; - class pre_order_iterator; - class post_order_iterator; - class sibling_iterator; - - tree(); - tree(const T&); - tree(const iterator_base&); - tree(const tree&); - ~tree(); - void operator=(const tree&); - -#ifdef __SGI_STL_PORT - class iterator_base : public stlport::bidirectional_iterator { -#else - class iterator_base { -#endif - public: - typedef T value_type; - typedef T* pointer; - typedef T& reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - - iterator_base(); - iterator_base(tree_node *); - - T& operator*() const; - T* operator->() const; - - void skip_children(); // do not iterate over children of this node - unsigned int number_of_children() const; - - sibling_iterator begin() const; - sibling_iterator end() const; - - tree_node *node; - protected: - bool skip_current_children_; - }; - - class pre_order_iterator : public iterator_base { - public: - pre_order_iterator(); - pre_order_iterator(tree_node *); - pre_order_iterator(const iterator_base&); - pre_order_iterator(const sibling_iterator&); - - bool operator==(const pre_order_iterator&) const; - bool operator!=(const pre_order_iterator&) const; - pre_order_iterator& operator++(); - pre_order_iterator& operator--(); - pre_order_iterator operator++(int); - pre_order_iterator operator--(int); - pre_order_iterator& operator+=(unsigned int); - pre_order_iterator& operator-=(unsigned int); - }; - - class post_order_iterator : public iterator_base { - public: - post_order_iterator(); - post_order_iterator(tree_node *); - post_order_iterator(const iterator_base&); - post_order_iterator(const sibling_iterator&); - - bool operator==(const post_order_iterator&) const; - bool operator!=(const post_order_iterator&) const; - post_order_iterator& operator++(); - post_order_iterator& operator--(); - post_order_iterator operator++(int); - post_order_iterator operator--(int); - post_order_iterator& operator+=(unsigned int); - post_order_iterator& operator-=(unsigned int); - - void descend_all(); - }; - - typedef pre_order_iterator iterator; - - class fixed_depth_iterator : public iterator_base { - public: - fixed_depth_iterator(); - fixed_depth_iterator(tree_node *); - fixed_depth_iterator(const iterator_base&); - fixed_depth_iterator(const sibling_iterator&); - fixed_depth_iterator(const fixed_depth_iterator&); - - bool operator==(const fixed_depth_iterator&) const; - bool operator!=(const fixed_depth_iterator&) const; - fixed_depth_iterator& operator++(); - fixed_depth_iterator& operator--(); - fixed_depth_iterator operator++(int); - fixed_depth_iterator operator--(int); - fixed_depth_iterator& operator+=(unsigned int); - fixed_depth_iterator& operator-=(unsigned int); - - tree_node *first_parent_; - private: - void set_first_parent_(); - void find_leftmost_parent_(); - }; - - class sibling_iterator : public iterator_base { - public: - sibling_iterator(); - sibling_iterator(tree_node *); - sibling_iterator(const sibling_iterator&); - sibling_iterator(const iterator_base&); - - bool operator==(const sibling_iterator&) const; - bool operator!=(const sibling_iterator&) const; - sibling_iterator& operator++(); - sibling_iterator& operator--(); - sibling_iterator operator++(int); - sibling_iterator operator--(int); - sibling_iterator& operator+=(unsigned int); - sibling_iterator& operator-=(unsigned int); - - tree_node *range_first() const; - tree_node *range_last() const; - tree_node *parent_; - private: - void set_parent_(); - }; - - // begin/end of tree - inline pre_order_iterator begin() const; - inline pre_order_iterator end() const; - post_order_iterator begin_post() const; - post_order_iterator end_post() const; - fixed_depth_iterator begin_fixed(const iterator_base&, unsigned int) const; - fixed_depth_iterator end_fixed(const iterator_base&, unsigned int) const; - // begin/end of children of node - sibling_iterator begin(const iterator_base&) const; - sibling_iterator end(const iterator_base&) const; - - template iter parent(iter) const; - template iter previous_sibling(iter) const; - template iter next_sibling(iter) const; - template iter next_at_same_depth(iter) const; - - void clear(); - // erase element at position pointed to by iterator, return incremented iterator - template iter erase(iter); - // erase all children of the node pointed to by iterator - void erase_children(const iterator_base&); - - // insert node as last child of node pointed to by position (first one inserts empty node) - template iter append_child(iter position); - template iter append_child(iter position, const T& x); - // the following two append nodes plus their children - template iter append_child(iter position, iter other_position); - template iter append_children(iter position, sibling_iterator from, sibling_iterator to); - - // short-hand to insert topmost node in otherwise empty tree - pre_order_iterator set_head(const T& x); - // insert node as previous sibling of node pointed to by position - template iter insert(iter position, const T& x); - // specialisation: insert node as previous sibling of node pointed to by position - //pre_order_iterator insert(sibling_iterator position, const T& x); - sibling_iterator insert(sibling_iterator position, const T& x); - // insert node (with children) pointed to by subtree as previous sibling of node pointed to by position - template iter insert_subtree(iter position, const iterator_base& subtree); - // insert node as next sibling of node pointed to by position - template iter insert_after(iter position, const T& x); - - // replace node at 'position' with other node (keeping same children); 'position' becomes invalid. - template iter replace(iter position, const T& x); - // replace node at 'position' with subtree starting at 'from' (do not erase subtree at 'from'); see above. - template iter replace(iter position, const iterator_base& from); - // replace string of siblings (plus their children) with copy of a new string (with children); see above - sibling_iterator replace(sibling_iterator orig_begin, sibling_iterator orig_end, - sibling_iterator new_begin, sibling_iterator new_end); - - // move all children of node at 'position' to be siblings, returns position - template iter flatten(iter position); - // move nodes in range to be children of 'position' - template iter reparent(iter position, sibling_iterator begin, sibling_iterator end); - // ditto, the range being all children of the 'from' node - template iter reparent(iter position, iter from); - - // new style move members, moving nodes plus children to a different location - template iter move_after(iter target, iter source); - template iter move_before(iter target, iter source); - template iter move_ontop(iter target, iter source); - - // merge with other tree, creating new branches and leaves only if they are not already present - void merge(sibling_iterator, sibling_iterator, sibling_iterator, sibling_iterator, - bool duplicate_leaves=false); - // sort (std::sort only moves values of nodes, this one moves children as well) - void sort(sibling_iterator from, sibling_iterator to, bool deep=false); - template - void sort(sibling_iterator from, sibling_iterator to, StrictWeakOrdering comp, bool deep=false); - // compare two ranges of nodes (compares nodes as well as tree structure) - template - bool equal(const iter& one, const iter& two, const iter& three) const; - template - bool equal(const iter& one, const iter& two, const iter& three, BinaryPredicate) const; - template - bool equal_subtree(const iter& one, const iter& two) const; - template - bool equal_subtree(const iter& one, const iter& two, BinaryPredicate) const; - // extract a new tree formed by the range of siblings plus all their children - tree subtree(sibling_iterator from, sibling_iterator to) const; - void subtree(tree&, sibling_iterator from, sibling_iterator to) const; - // exchange the node (plus subtree) with its sibling node (do nothing if no sibling present) - void swap(sibling_iterator it); - // find a subtree -// template -// iterator find_subtree(sibling_iterator, sibling_iterator, iterator from, iterator to, BinaryPredicate) const; - - // count the total number of nodes - int size() const; - // check if tree is empty - bool empty() const; - // compute the depth to the root - int depth(const iterator_base&) const; - // count the number of children of node at position - unsigned int number_of_children(const iterator_base&) const; - // count the number of 'next' siblings of node at iterator - unsigned int number_of_siblings(const iterator_base&) const; - // determine whether node at position is in the subtrees with root in the range - bool is_in_subtree(const iterator_base& position, const iterator_base& begin, - const iterator_base& end) const; - // determine whether the iterator is an 'end' iterator and thus not actually - // pointing to a node - bool is_valid(const iterator_base&) const; - - // determine the index of a node in the range of siblings to which it belongs. - unsigned int index(sibling_iterator it) const; - // inverse of 'index': return the n-th child of the node at position - sibling_iterator child(const iterator_base& position, unsigned int) const; - - class iterator_base_less { - public: - bool operator()(const typename tree::iterator_base& one, - const typename tree::iterator_base& two) const - { - return one.node < two.node; - } - }; - tree_node *head, *feet; // head/feet are always dummy; if an iterator points to them it is invalid - private: - tree_node_allocator alloc_; - void head_initialise_(); - void copy_(const tree& other); - template - class compare_nodes { - public: - bool operator()(const tree_node *a, const tree_node *b) - { - static StrictWeakOrdering comp; - return comp(a->data, b->data); - } - }; -}; - -//template -//class iterator_base_less { -// public: -// bool operator()(const typename tree::iterator_base& one, -// const typename tree::iterator_base& two) const -// { -// txtout << "operatorclass<" << one.node < two.node << std::endl; -// return one.node < two.node; -// } -//}; - -//template -//bool operator<(const typename tree::iterator& one, -// const typename tree::iterator& two) -// { -// txtout << "operator< " << one.node < two.node << std::endl; -// if(one.node < two.node) return true; -// return false; -// } - -template -bool operator>(const typename tree::iterator_base& one, - const typename tree::iterator_base& two) - { - if(one.node > two.node) return true; - return false; - } - - - -// Tree - -template -tree::tree() - { - head_initialise_(); - } - -template -tree::tree(const T& x) - { - head_initialise_(); - set_head(x); - } - -template -tree::tree(const iterator_base& other) - { - head_initialise_(); - set_head((*other)); - replace(begin(), other); - } - -template -tree::~tree() - { - clear(); - alloc_.deallocate(head,1); - alloc_.deallocate(feet,1); - } - -template -void tree::head_initialise_() - { - head = alloc_.allocate(1,0); // MSVC does not have default second argument - feet = alloc_.allocate(1,0); - - head->parent=0; - head->first_child=0; - head->last_child=0; - head->prev_sibling=0; //head; - head->next_sibling=feet; //head; - - feet->parent=0; - feet->first_child=0; - feet->last_child=0; - feet->prev_sibling=head; - feet->next_sibling=0; - } - -template -void tree::operator=(const tree& other) - { - copy_(other); - } - -template -tree::tree(const tree& other) - { - head_initialise_(); - copy_(other); - } - -template -void tree::copy_(const tree& other) - { - clear(); - pre_order_iterator it=other.begin(), to=begin(); - while(it!=other.end()) { - to=insert(to, (*it)); - it.skip_children(); - ++it; - } - to=begin(); - it=other.begin(); - while(it!=other.end()) { - to=replace(to, it); - to.skip_children(); - it.skip_children(); - ++to; - ++it; - } - } - -template -void tree::clear() - { - if(head) - while(head->next_sibling!=feet) - erase(pre_order_iterator(head->next_sibling)); - } - -template -void tree::erase_children(const iterator_base& it) - { - tree_node *cur=it.node->first_child; - tree_node *prev=0; - - while(cur!=0) { - prev=cur; - cur=cur->next_sibling; - erase_children(pre_order_iterator(prev)); - kp::destructor(&prev->data); - alloc_.deallocate(prev,1); - } - it.node->first_child=0; - it.node->last_child=0; - } - -template -template -iter tree::erase(iter it) - { - tree_node *cur=it.node; - assert(cur!=head); - iter ret=it; - ret.skip_children(); - ++ret; - erase_children(it); - if(cur->prev_sibling==0) { - cur->parent->first_child=cur->next_sibling; - } - else { - cur->prev_sibling->next_sibling=cur->next_sibling; - } - if(cur->next_sibling==0) { - cur->parent->last_child=cur->prev_sibling; - } - else { - cur->next_sibling->prev_sibling=cur->prev_sibling; - } - - kp::destructor(&cur->data); - alloc_.deallocate(cur,1); - return ret; - } - -template -typename tree::pre_order_iterator tree::begin() const - { - return pre_order_iterator(head->next_sibling); - } - -template -typename tree::pre_order_iterator tree::end() const - { - return pre_order_iterator(feet); - } - -template -typename tree::post_order_iterator tree::begin_post() const - { - tree_node *tmp=head->next_sibling; - if(tmp!=feet) { - while(tmp->first_child) - tmp=tmp->first_child; - } - return post_order_iterator(tmp); - } - -template -typename tree::post_order_iterator tree::end_post() const - { - return post_order_iterator(feet); - } - -template -typename tree::fixed_depth_iterator tree::begin_fixed(const iterator_base& pos, unsigned int dp) const - { - tree_node *tmp=pos.node; - unsigned int curdepth=0; - while(curdepthfirst_child==0) { - tmp=tmp->next_sibling; - if(tmp==0) - throw std::range_error("tree: begin_fixed out of range"); - } - tmp=tmp->first_child; - ++curdepth; - } - return tmp; - } - -template -typename tree::fixed_depth_iterator tree::end_fixed(const iterator_base& pos, unsigned int dp) const - { - assert(1==0); // FIXME: not correct yet - tree_node *tmp=pos.node; - unsigned int curdepth=1; - while(curdepthfirst_child==0) { - tmp=tmp->next_sibling; - if(tmp==0) - throw std::range_error("tree: end_fixed out of range"); - } - tmp=tmp->first_child; - ++curdepth; - } - return tmp; - } - -template -typename tree::sibling_iterator tree::begin(const iterator_base& pos) const - { - if(pos.node->first_child==0) { - return end(pos); - } - return pos.node->first_child; - } - -template -typename tree::sibling_iterator tree::end(const iterator_base& pos) const - { - sibling_iterator ret(0); - ret.parent_=pos.node; - return ret; - } - -template -template -iter tree::parent(iter position) const - { - assert(position.node!=0); - return iter(position.node->parent); - } - -template -template -iter tree::previous_sibling(iter position) const - { - assert(position.node!=0); - iter ret(position); - ret.node=position.node->prev_sibling; - return ret; - } - -template -template -iter tree::next_sibling(iter position) const - { - assert(position.node!=0); - iter ret(position); - ret.node=position.node->next_sibling; - return ret; - } - -template -template -iter tree::next_at_same_depth(iter position) const - { - assert(position.node!=0); - iter ret(position); - - if(position.node->next_sibling) { - ret.node=position.node->next_sibling; - } - else { - int relative_depth=0; - upper: - do { - ret.node=ret.node->parent; - if(ret.node==0) return ret; - --relative_depth; - } while(ret.node->next_sibling==0); - lower: - ret.node=ret.node->next_sibling; - while(ret.node->first_child==0) { - if(ret.node->next_sibling==0) - goto upper; - ret.node=ret.node->next_sibling; - if(ret.node==0) return ret; - } - while(relative_depth<0 && ret.node->first_child!=0) { - ret.node=ret.node->first_child; - ++relative_depth; - } - if(relative_depth<0) { - if(ret.node->next_sibling==0) goto upper; - else goto lower; - } - } - return ret; - } - -template -template -iter tree::append_child(iter position) - { - assert(position.node!=head); - - tree_node* tmp = alloc_.allocate(1,0); - kp::constructor(&tmp->data); - tmp->first_child=0; - tmp->last_child=0; - - tmp->parent=position.node; - if(position.node->last_child!=0) { - position.node->last_child->next_sibling=tmp; - } - else { - position.node->first_child=tmp; - } - tmp->prev_sibling=position.node->last_child; - position.node->last_child=tmp; - tmp->next_sibling=0; - return tmp; - } - -template -template -iter tree::append_child(iter position, const T& x) - { - // If your program fails here you probably used 'append_child' to add the top - // node to an empty tree. From version 1.45 the top element should be added - // using 'insert'. See the documentation for further information, and sorry about - // the API change. - assert(position.node!=head); - - tree_node* tmp = alloc_.allocate(1,0); - kp::constructor(&tmp->data, x); - tmp->first_child=0; - tmp->last_child=0; - - tmp->parent=position.node; - if(position.node->last_child!=0) { - position.node->last_child->next_sibling=tmp; - } - else { - position.node->first_child=tmp; - } - tmp->prev_sibling=position.node->last_child; - position.node->last_child=tmp; - tmp->next_sibling=0; - return tmp; - } - -template -template -iter tree::append_child(iter position, iter other) - { - assert(position.node!=head); - - sibling_iterator aargh=append_child(position, value_type()); - return replace(aargh, other); - } - -template -template -iter tree::append_children(iter position, sibling_iterator from, sibling_iterator to) - { - iter ret=from; - - while(from!=to) { - insert_subtree(position.end(), from); - ++from; - } - return ret; - } - -template -typename tree::pre_order_iterator tree::set_head(const T& x) - { - assert(head->next_sibling==feet); - return insert(iterator(feet), x); - } - -template -template -iter tree::insert(iter position, const T& x) - { - if(position.node==0) { - position.node=feet; // Backward compatibility: when calling insert on a null node, - // insert before the feet. - } - tree_node* tmp = alloc_.allocate(1,0); - kp::constructor(&tmp->data, x); - tmp->first_child=0; - tmp->last_child=0; - - tmp->parent=position.node->parent; - tmp->next_sibling=position.node; - tmp->prev_sibling=position.node->prev_sibling; - position.node->prev_sibling=tmp; - - if(tmp->prev_sibling==0) { - if(tmp->parent) // when inserting nodes at the head, there is no parent - tmp->parent->first_child=tmp; - } - else - tmp->prev_sibling->next_sibling=tmp; - return tmp; - } - -template -typename tree::sibling_iterator tree::insert(sibling_iterator position, const T& x) - { - tree_node* tmp = alloc_.allocate(1,0); - kp::constructor(&tmp->data, x); - tmp->first_child=0; - tmp->last_child=0; - - tmp->next_sibling=position.node; - if(position.node==0) { // iterator points to end of a subtree - tmp->parent=position.parent_; - tmp->prev_sibling=position.range_last(); - tmp->parent->last_child=tmp; - } - else { - tmp->parent=position.node->parent; - tmp->prev_sibling=position.node->prev_sibling; - position.node->prev_sibling=tmp; - } - - if(tmp->prev_sibling==0) { - if(tmp->parent) // when inserting nodes at the head, there is no parent - tmp->parent->first_child=tmp; - } - else - tmp->prev_sibling->next_sibling=tmp; - return tmp; - } - -template -template -iter tree::insert_after(iter position, const T& x) - { - tree_node* tmp = alloc_.allocate(1,0); - kp::constructor(&tmp->data, x); - tmp->first_child=0; - tmp->last_child=0; - - tmp->parent=position.node->parent; - tmp->prev_sibling=position.node; - tmp->next_sibling=position.node->next_sibling; - position.node->next_sibling=tmp; - - if(tmp->next_sibling==0) { - if(tmp->parent) // when inserting nodes at the head, there is no parent - tmp->parent->last_child=tmp; - } - else { - tmp->next_sibling->prev_sibling=tmp; - } - return tmp; - } - -template -template -iter tree::insert_subtree(iter position, const iterator_base& subtree) - { - // insert dummy - iter it=insert(position, value_type()); - // replace dummy with subtree - return replace(it, subtree); - } - -// template -// template -// iter tree::insert_subtree(sibling_iterator position, iter subtree) -// { -// // insert dummy -// iter it(insert(position, value_type())); -// // replace dummy with subtree -// return replace(it, subtree); -// } - -template -template -iter tree::replace(iter position, const T& x) - { - kp::destructor(&position.node->data); - kp::constructor(&position.node->data, x); - return position; - } - -template -template -iter tree::replace(iter position, const iterator_base& from) - { - assert(position.node!=head); - tree_node *current_from=from.node; - tree_node *start_from=from.node; - tree_node *current_to =position.node; - - // replace the node at position with head of the replacement tree at from - erase_children(position); - tree_node* tmp = alloc_.allocate(1,0); - kp::constructor(&tmp->data, (*from)); - tmp->first_child=0; - tmp->last_child=0; - if(current_to->prev_sibling==0) { - current_to->parent->first_child=tmp; - } - else { - current_to->prev_sibling->next_sibling=tmp; - } - tmp->prev_sibling=current_to->prev_sibling; - if(current_to->next_sibling==0) { - current_to->parent->last_child=tmp; - } - else { - current_to->next_sibling->prev_sibling=tmp; - } - tmp->next_sibling=current_to->next_sibling; - tmp->parent=current_to->parent; - kp::destructor(¤t_to->data); - alloc_.deallocate(current_to,1); - current_to=tmp; - - // only at this stage can we fix 'last' - tree_node *last=from.node->next_sibling; - - pre_order_iterator toit=tmp; - // copy all children - do { - assert(current_from!=0); - if(current_from->first_child != 0) { - current_from=current_from->first_child; - toit=append_child(toit, current_from->data); - } - else { - while(current_from->next_sibling==0 && current_from!=start_from) { - current_from=current_from->parent; - toit=parent(toit); - assert(current_from!=0); - } - current_from=current_from->next_sibling; - if(current_from!=last) { - toit=append_child(parent(toit), current_from->data); - } - } - } while(current_from!=last); - - return current_to; - } - -template -typename tree::sibling_iterator tree::replace( - sibling_iterator orig_begin, - sibling_iterator orig_end, - sibling_iterator new_begin, - sibling_iterator new_end) - { - tree_node *orig_first=orig_begin.node; - tree_node *new_first=new_begin.node; - tree_node *orig_last=orig_first; - while((++orig_begin)!=orig_end) - orig_last=orig_last->next_sibling; - tree_node *new_last=new_first; - while((++new_begin)!=new_end) - new_last=new_last->next_sibling; - - // insert all siblings in new_first..new_last before orig_first - bool first=true; - pre_order_iterator ret; - while(1==1) { - pre_order_iterator tt=insert_subtree(pre_order_iterator(orig_first), pre_order_iterator(new_first)); - if(first) { - ret=tt; - first=false; - } - if(new_first==new_last) - break; - new_first=new_first->next_sibling; - } - - // erase old range of siblings - bool last=false; - tree_node *next=orig_first; - while(1==1) { - if(next==orig_last) - last=true; - next=next->next_sibling; - erase((pre_order_iterator)orig_first); - if(last) - break; - orig_first=next; - } - return ret; - } - -template -template -iter tree::flatten(iter position) - { - if(position.node->first_child==0) - return position; - - tree_node *tmp=position.node->first_child; - while(tmp) { - tmp->parent=position.node->parent; - tmp=tmp->next_sibling; - } - if(position.node->next_sibling) { - position.node->last_child->next_sibling=position.node->next_sibling; - position.node->next_sibling->prev_sibling=position.node->last_child; - } - else { - position.node->parent->last_child=position.node->last_child; - } - position.node->next_sibling=position.node->first_child; - position.node->next_sibling->prev_sibling=position.node; - position.node->first_child=0; - position.node->last_child=0; - - return position; - } - - -template -template -iter tree::reparent(iter position, sibling_iterator begin, sibling_iterator end) - { - tree_node *first=begin.node; - tree_node *last=first; - if(begin==end) return begin; - // determine last node - while((++begin)!=end) { - last=last->next_sibling; - } - // move subtree - if(first->prev_sibling==0) { - first->parent->first_child=last->next_sibling; - } - else { - first->prev_sibling->next_sibling=last->next_sibling; - } - if(last->next_sibling==0) { - last->parent->last_child=first->prev_sibling; - } - else { - last->next_sibling->prev_sibling=first->prev_sibling; - } - if(position.node->first_child==0) { - position.node->first_child=first; - position.node->last_child=last; - first->prev_sibling=0; - } - else { - position.node->last_child->next_sibling=first; - first->prev_sibling=position.node->last_child; - position.node->last_child=last; - } - last->next_sibling=0; - - tree_node *pos=first; - while(1==1) { - pos->parent=position.node; - if(pos==last) break; - pos=pos->next_sibling; - } - - return first; - } - -template -template iter tree::reparent(iter position, iter from) - { - if(from.node->first_child==0) return position; - return reparent(position, from.node->first_child, end(from)); - } - -template -template iter tree::move_before(iter target, iter source) - { - tree_node *dst=target.node; - tree_node *src=source.node; - assert(dst); - assert(src); - - if(dst==src) return source; - - // take src out of the tree - if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling; - else src->parent->first_child=src->next_sibling; - if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling; - else src->parent->last_child=src->prev_sibling; - - // connect it to the new point - if(dst->prev_sibling!=0) dst->prev_sibling->next_sibling=src; - else dst->parent->first_child=src; - src->prev_sibling=dst->prev_sibling; - dst->prev_sibling=src; - src->next_sibling=dst; - src->parent=dst->parent; - return src; - } - -template -template iter tree::move_ontop(iter target, iter source) - { - tree_node *dst=target.node; - tree_node *src=source.node; - assert(dst); - assert(src); - - if(dst==src) return source; - - // remember connection points - tree_node *b_prev_sibling=dst->prev_sibling; - tree_node *b_next_sibling=dst->next_sibling; - tree_node *b_parent=dst->parent; - - // remove target - erase(target); - - // take src out of the tree - if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling; - else src->parent->first_child=src->next_sibling; - if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling; - else src->parent->last_child=src->prev_sibling; - - // connect it to the new point - if(b_prev_sibling!=0) b_prev_sibling->next_sibling=src; - else b_parent->first_child=src; - if(b_next_sibling!=0) b_next_sibling->prev_sibling=src; - else b_parent->last_child=src; - src->prev_sibling=b_prev_sibling; - src->next_sibling=b_next_sibling; - src->parent=b_parent; - return src; - } - -template -void tree::merge(sibling_iterator to1, sibling_iterator to2, - sibling_iterator from1, sibling_iterator from2, - bool duplicate_leaves) - { - sibling_iterator fnd; - while(from1!=from2) { - if((fnd=std::find(to1, to2, (*from1))) != to2) { // element found - if(from1.begin()==from1.end()) { // full depth reached - if(duplicate_leaves) - append_child(parent(to1), (*from1)); - } - else { // descend further - merge(fnd.begin(), fnd.end(), from1.begin(), from1.end(), duplicate_leaves); - } - } - else { // element missing - insert_subtree(to2, from1); - } - ++from1; - } - } - - -template -void tree::sort(sibling_iterator from, sibling_iterator to, bool deep) - { - std::less comp; - sort(from, to, comp, deep); - } - -template -template -void tree::sort(sibling_iterator from, sibling_iterator to, - StrictWeakOrdering comp, bool deep) - { - if(from==to) return; - // make list of sorted nodes - // CHECK: if multiset stores equivalent nodes in the order in which they - // are inserted, then this routine should be called 'stable_sort'. - std::multiset > nodes; - sibling_iterator it=from, it2=to; - while(it != to) { - nodes.insert(it.node); - ++it; - } - // reassemble - --it2; - - // prev and next are the nodes before and after the sorted range - tree_node *prev=from.node->prev_sibling; - tree_node *next=it2.node->next_sibling; - typename std::multiset >::iterator nit=nodes.begin(), eit=nodes.end(); - if(prev==0) { - if((*nit)->parent!=0) // to catch "sorting the head" situations, when there is no parent - (*nit)->parent->first_child=(*nit); - } - else prev->next_sibling=(*nit); - - --eit; - while(nit!=eit) { - (*nit)->prev_sibling=prev; - if(prev) - prev->next_sibling=(*nit); - prev=(*nit); - ++nit; - } - // prev now points to the last-but-one node in the sorted range - if(prev) - prev->next_sibling=(*eit); - - // eit points to the last node in the sorted range. - (*eit)->next_sibling=next; - (*eit)->prev_sibling=prev; // missed in the loop above - if(next==0) { - if((*eit)->parent!=0) // to catch "sorting the head" situations, when there is no parent - (*eit)->parent->last_child=(*eit); - } - else next->prev_sibling=(*eit); - - if(deep) { // sort the children of each node too - sibling_iterator bcs(*nodes.begin()); - sibling_iterator ecs(*eit); - ++ecs; - while(bcs!=ecs) { - sort(begin(bcs), end(bcs), comp, deep); - ++bcs; - } - } - } - -template -template -bool tree::equal(const iter& one_, const iter& two, const iter& three_) const - { - std::equal_to comp; - return equal(one_, two, three_, comp); - } - -template -template -bool tree::equal_subtree(const iter& one_, const iter& two_) const - { - std::equal_to comp; - return equal_subtree(one_, two_, comp); - } - -template -template -bool tree::equal(const iter& one_, const iter& two, const iter& three_, BinaryPredicate fun) const - { - pre_order_iterator one(one_), three(three_); - -// if(one==two && is_valid(three) && three.number_of_children()!=0) -// return false; - while(one!=two && is_valid(three)) { - if(!fun(*one,*three)) - return false; - if(one.number_of_children()!=three.number_of_children()) - return false; - ++one; - ++three; - } - return true; - } - -template -template -bool tree::equal_subtree(const iter& one_, const iter& two_, BinaryPredicate fun) const - { - pre_order_iterator one(one_), two(two_); - - if(!fun(*one,*two)) return false; - if(number_of_children(one)!=number_of_children(two)) return false; - return equal(begin(one),end(one),begin(two),fun); - } - -template -tree tree::subtree(sibling_iterator from, sibling_iterator to) const - { - tree tmp; - tmp.set_head(value_type()); - tmp.replace(tmp.begin(), tmp.end(), from, to); - return tmp; - } - -template -void tree::subtree(tree& tmp, sibling_iterator from, sibling_iterator to) const - { - tmp.set_head(value_type()); - tmp.replace(tmp.begin(), tmp.end(), from, to); - } - -template -int tree::size() const - { - int i=0; - pre_order_iterator it=begin(), eit=end(); - while(it!=eit) { - ++i; - ++it; - } - return i; - } - -template -bool tree::empty() const - { - pre_order_iterator it=begin(), eit=end(); - return (it==eit); - } - -template -int tree::depth(const iterator_base& it) const - { - tree_node* pos=it.node; - assert(pos!=0); - int ret=0; - while(pos->parent!=0) { - pos=pos->parent; - ++ret; - } - return ret; - } - -template -unsigned int tree::number_of_children(const iterator_base& it) const - { - tree_node *pos=it.node->first_child; - if(pos==0) return 0; - - unsigned int ret=1; -// while(pos!=it.node->last_child) { -// ++ret; -// pos=pos->next_sibling; -// } - while((pos=pos->next_sibling)) - ++ret; - return ret; - } - -template -unsigned int tree::number_of_siblings(const iterator_base& it) const - { - tree_node *pos=it.node; - unsigned int ret=0; - while(pos->next_sibling && - pos->next_sibling!=head && - pos->next_sibling!=feet) { - ++ret; - pos=pos->next_sibling; - } - return ret; - } - -template -void tree::swap(sibling_iterator it) - { - tree_node *nxt=it.node->next_sibling; - if(nxt) { - if(it.node->prev_sibling) - it.node->prev_sibling->next_sibling=nxt; - else - it.node->parent->first_child=nxt; - nxt->prev_sibling=it.node->prev_sibling; - tree_node *nxtnxt=nxt->next_sibling; - if(nxtnxt) - nxtnxt->prev_sibling=it.node; - else - it.node->parent->last_child=it.node; - nxt->next_sibling=it.node; - it.node->prev_sibling=nxt; - it.node->next_sibling=nxtnxt; - } - } - -// template -// tree::iterator tree::find_subtree( -// sibling_iterator subfrom, sibling_iterator subto, iterator from, iterator to, -// BinaryPredicate fun) const -// { -// assert(1==0); // this routine is not finished yet. -// while(from!=to) { -// if(fun(*subfrom, *from)) { -// -// } -// } -// return to; -// } - -template -bool tree::is_in_subtree(const iterator_base& it, const iterator_base& begin, - const iterator_base& end) const - { - // FIXME: this should be optimised. - pre_order_iterator tmp=begin; - while(tmp!=end) { - if(tmp==it) return true; - ++tmp; - } - return false; - } - -template -bool tree::is_valid(const iterator_base& it) const - { - if(it.node==0 || it.node==feet) return false; - else return true; - } - -template -unsigned int tree::index(sibling_iterator it) const - { - unsigned int ind=0; - if(it.node->parent==0) { - while(it.node->prev_sibling!=head) { - it.node=it.node->prev_sibling; - ++ind; - } - } - else { - while(it.node->prev_sibling!=0) { - it.node=it.node->prev_sibling; - ++ind; - } - } - return ind; - } - - -template -typename tree::sibling_iterator tree::child(const iterator_base& it, unsigned int num) const - { - tree_node *tmp=it.node->first_child; - while(num--) { - assert(tmp!=0); - tmp=tmp->next_sibling; - } - return tmp; - } - - - - -// Iterator base - -template -tree::iterator_base::iterator_base() - : node(0), skip_current_children_(false) - { - } - -template -tree::iterator_base::iterator_base(tree_node *tn) - : node(tn), skip_current_children_(false) - { - } - -template -T& tree::iterator_base::operator*() const - { - return node->data; - } - -template -T* tree::iterator_base::operator->() const - { - return &(node->data); - } - -template -bool tree::post_order_iterator::operator!=(const post_order_iterator& other) const - { - if(other.node!=this->node) return true; - else return false; - } - -template -bool tree::post_order_iterator::operator==(const post_order_iterator& other) const - { - if(other.node==this->node) return true; - else return false; - } - -template -bool tree::pre_order_iterator::operator!=(const pre_order_iterator& other) const - { - if(other.node!=this->node) return true; - else return false; - } - -template -bool tree::pre_order_iterator::operator==(const pre_order_iterator& other) const - { - if(other.node==this->node) return true; - else return false; - } - -template -bool tree::sibling_iterator::operator!=(const sibling_iterator& other) const - { - if(other.node!=this->node) return true; - else return false; - } - -template -bool tree::sibling_iterator::operator==(const sibling_iterator& other) const - { - if(other.node==this->node) return true; - else return false; - } - -template -typename tree::sibling_iterator tree::iterator_base::begin() const - { - sibling_iterator ret(node->first_child); - ret.parent_=this->node; - return ret; - } - -template -typename tree::sibling_iterator tree::iterator_base::end() const - { - sibling_iterator ret(0); - ret.parent_=node; - return ret; - } - -template -void tree::iterator_base::skip_children() - { - skip_current_children_=true; - } - -template -unsigned int tree::iterator_base::number_of_children() const - { - tree_node *pos=node->first_child; - if(pos==0) return 0; - - unsigned int ret=1; - while(pos!=node->last_child) { - ++ret; - pos=pos->next_sibling; - } - return ret; - } - - - -// Pre-order iterator - -template -tree::pre_order_iterator::pre_order_iterator() - : iterator_base(0) - { - } - -template -tree::pre_order_iterator::pre_order_iterator(tree_node *tn) - : iterator_base(tn) - { - } - -template -tree::pre_order_iterator::pre_order_iterator(const iterator_base &other) - : iterator_base(other.node) - { - } - -template -tree::pre_order_iterator::pre_order_iterator(const sibling_iterator& other) - : iterator_base(other.node) - { - if(this->node==0) { - if(other.range_last()!=0) - this->node=other.range_last(); - else - this->node=other.parent_; - this->skip_children(); - ++(*this); - } - } - -template -typename tree::pre_order_iterator& tree::pre_order_iterator::operator++() - { - assert(this->node!=0); - if(!this->skip_current_children_ && this->node->first_child != 0) { - this->node=this->node->first_child; - } - else { - this->skip_current_children_=false; - while(this->node->next_sibling==0) { - this->node=this->node->parent; - if(this->node==0) - return *this; - } - this->node=this->node->next_sibling; - } - return *this; - } - -template -typename tree::pre_order_iterator& tree::pre_order_iterator::operator--() - { - assert(this->node!=0); - if(this->node->prev_sibling) { - this->node=this->node->prev_sibling; - while(this->node->last_child) - this->node=this->node->last_child; - } - else { - this->node=this->node->parent; - if(this->node==0) - return *this; - } - return *this; -} - -template -typename tree::pre_order_iterator tree::pre_order_iterator::operator++(int n) - { - pre_order_iterator copy = *this; - ++(*this); - return copy; - } - -template -typename tree::pre_order_iterator tree::pre_order_iterator::operator--(int n) -{ - pre_order_iterator copy = *this; - --(*this); - return copy; -} - -template -typename tree::pre_order_iterator& tree::pre_order_iterator::operator+=(unsigned int num) - { - while(num>0) { - ++(*this); - --num; - } - return (*this); - } - -template -typename tree::pre_order_iterator& tree::pre_order_iterator::operator-=(unsigned int num) - { - while(num>0) { - --(*this); - --num; - } - return (*this); - } - - - -// Post-order iterator - -template -tree::post_order_iterator::post_order_iterator() - : iterator_base(0) - { - } - -template -tree::post_order_iterator::post_order_iterator(tree_node *tn) - : iterator_base(tn) - { - } - -template -tree::post_order_iterator::post_order_iterator(const iterator_base &other) - : iterator_base(other.node) - { - } - -template -tree::post_order_iterator::post_order_iterator(const sibling_iterator& other) - : iterator_base(other.node) - { - if(this->node==0) { - if(other.range_last()!=0) - this->node=other.range_last(); - else - this->node=other.parent_; - this->skip_children(); - ++(*this); - } - } - -template -typename tree::post_order_iterator& tree::post_order_iterator::operator++() - { - assert(this->node!=0); - if(this->node->next_sibling==0) - this->node=this->node->parent; - else { - this->node=this->node->next_sibling; - if(this->skip_current_children_) { - this->skip_current_children_=false; - } - else { - while(this->node->first_child) - this->node=this->node->first_child; - } - } - return *this; - } - -template -typename tree::post_order_iterator& tree::post_order_iterator::operator--() - { - assert(this->node!=0); - if(this->skip_current_children_ || this->node->last_child==0) { - this->skip_current_children_=false; - while(this->node->prev_sibling==0) - this->node=this->node->parent; - this->node=this->node->prev_sibling; - } - else { - this->node=this->node->last_child; - } - return *this; -} - -template -typename tree::post_order_iterator tree::post_order_iterator::operator++(int) - { - post_order_iterator copy = *this; - ++(*this); - return copy; - } - -template -typename tree::post_order_iterator tree::post_order_iterator::operator--(int) - { - post_order_iterator copy = *this; - --(*this); - return copy; - } - - -template -typename tree::post_order_iterator& tree::post_order_iterator::operator+=(unsigned int num) - { - while(num>0) { - ++(*this); - --num; - } - return (*this); - } - -template -typename tree::post_order_iterator& tree::post_order_iterator::operator-=(unsigned int num) - { - while(num>0) { - --(*this); - --num; - } - return (*this); - } - -template -void tree::post_order_iterator::descend_all() - { - assert(this->node!=0); - while(this->node->first_child) - this->node=this->node->first_child; - } - - -// Fixed depth iterator - -template -tree::fixed_depth_iterator::fixed_depth_iterator() - : iterator_base() - { - set_first_parent_(); - } - -template -tree::fixed_depth_iterator::fixed_depth_iterator(tree_node *tn) - : iterator_base(tn) - { - set_first_parent_(); - } - -template -tree::fixed_depth_iterator::fixed_depth_iterator(const iterator_base& other) - : iterator_base(other.node) - { - set_first_parent_(); - } - -template -tree::fixed_depth_iterator::fixed_depth_iterator(const sibling_iterator& other) - : iterator_base(other.node), first_parent_(other.parent_) - { - find_leftmost_parent_(); - } - -template -tree::fixed_depth_iterator::fixed_depth_iterator(const fixed_depth_iterator& other) - : iterator_base(other.node), first_parent_(other.first_parent_) - { - } - -template -void tree::fixed_depth_iterator::set_first_parent_() - { - return; // FIXME: we do not use first_parent_ yet, and it actually needs some serious reworking if - // it is ever to work at the 'head' level. - first_parent_=0; - if(this->node==0) return; - if(this->node->parent!=0) - first_parent_=this->node->parent; - if(first_parent_) - find_leftmost_parent_(); - } - -template -void tree::fixed_depth_iterator::find_leftmost_parent_() - { - return; // FIXME: see 'set_first_parent()' - tree_node *tmppar=first_parent_; - while(tmppar->prev_sibling) { - tmppar=tmppar->prev_sibling; - if(tmppar->first_child) - first_parent_=tmppar; - } - } - -template -typename tree::fixed_depth_iterator& tree::fixed_depth_iterator::operator++() - { - assert(this->node!=0); - - if(this->node->next_sibling) { - this->node=this->node->next_sibling; - } - else { - int relative_depth=0; - upper: - do { - this->node=this->node->parent; - if(this->node==0) return *this; - --relative_depth; - } while(this->node->next_sibling==0); - lower: - this->node=this->node->next_sibling; - while(this->node->first_child==0) { - if(this->node->next_sibling==0) - goto upper; - this->node=this->node->next_sibling; - if(this->node==0) return *this; - } - while(relative_depth<0 && this->node->first_child!=0) { - this->node=this->node->first_child; - ++relative_depth; - } - if(relative_depth<0) { - if(this->node->next_sibling==0) goto upper; - else goto lower; - } - } - return *this; - -// if(this->node->next_sibling!=0) { -// this->node=this->node->next_sibling; -// assert(this->node!=0); -// if(this->node->parent==0 && this->node->next_sibling==0) // feet element -// this->node=0; -// } -// else { -// tree_node *par=this->node->parent; -// do { -// par=par->next_sibling; -// if(par==0) { // FIXME: need to keep track of this! -// this->node=0; -// return *this; -// } -// } while(par->first_child==0); -// this->node=par->first_child; -// } - return *this; - } - -template -typename tree::fixed_depth_iterator& tree::fixed_depth_iterator::operator--() - { - assert(this->node!=0); - if(this->node->prev_sibling!=0) { - this->node=this->node->prev_sibling; - assert(this->node!=0); - if(this->node->parent==0 && this->node->prev_sibling==0) // head element - this->node=0; - } - else { - tree_node *par=this->node->parent; - do { - par=par->prev_sibling; - if(par==0) { // FIXME: need to keep track of this! - this->node=0; - return *this; - } - } while(par->last_child==0); - this->node=par->last_child; - } - return *this; -} - -template -typename tree::fixed_depth_iterator tree::fixed_depth_iterator::operator++(int) - { - fixed_depth_iterator copy = *this; - ++(*this); - return copy; - } - -template -typename tree::fixed_depth_iterator tree::fixed_depth_iterator::operator--(int) -{ - fixed_depth_iterator copy = *this; - --(*this); - return copy; -} - -template -typename tree::fixed_depth_iterator& tree::fixed_depth_iterator::operator-=(unsigned int num) - { - while(num>0) { - --(*this); - --(num); - } - return (*this); - } - -template -typename tree::fixed_depth_iterator& tree::fixed_depth_iterator::operator+=(unsigned int num) - { - while(num>0) { - ++(*this); - --(num); - } - return *this; - } - -// FIXME: add the other members of fixed_depth_iterator. - - -// Sibling iterator - -template -tree::sibling_iterator::sibling_iterator() - : iterator_base() - { - set_parent_(); - } - -template -tree::sibling_iterator::sibling_iterator(tree_node *tn) - : iterator_base(tn) - { - set_parent_(); - } - -template -tree::sibling_iterator::sibling_iterator(const iterator_base& other) - : iterator_base(other.node) - { - set_parent_(); - } - -template -tree::sibling_iterator::sibling_iterator(const sibling_iterator& other) - : iterator_base(other), parent_(other.parent_) - { - } - -template -void tree::sibling_iterator::set_parent_() - { - parent_=0; - if(this->node==0) return; - if(this->node->parent!=0) - parent_=this->node->parent; - } - -template -typename tree::sibling_iterator& tree::sibling_iterator::operator++() - { - if(this->node) - this->node=this->node->next_sibling; - return *this; - } - -template -typename tree::sibling_iterator& tree::sibling_iterator::operator--() - { - if(this->node) this->node=this->node->prev_sibling; - else { - assert(parent_); - this->node=parent_->last_child; - } - return *this; -} - -template -typename tree::sibling_iterator tree::sibling_iterator::operator++(int) - { - sibling_iterator copy = *this; - ++(*this); - return copy; - } - -template -typename tree::sibling_iterator tree::sibling_iterator::operator--(int) - { - sibling_iterator copy = *this; - --(*this); - return copy; - } - -template -typename tree::sibling_iterator& tree::sibling_iterator::operator+=(unsigned int num) - { - while(num>0) { - ++(*this); - --num; - } - return (*this); - } - -template -typename tree::sibling_iterator& tree::sibling_iterator::operator-=(unsigned int num) - { - while(num>0) { - --(*this); - --num; - } - return (*this); - } - -template -typename tree::tree_node *tree::sibling_iterator::range_first() const - { - tree_node *tmp=parent_->first_child; - return tmp; - } - -template -typename tree::tree_node *tree::sibling_iterator::range_last() const - { - return parent_->last_child; - } - - -#endif - -// Local variables: -// default-tab-width: 3 -// End: