/* 
     $Id: tree_msvc.hh,v 1.3 2002/05/28 11:53:25 t16 Exp $
  	STL-like templated tree class.
	Copyright (C) 2001  Kasper Peeters <k.peeters@damtp.cam.ac.uk>
     Microsoft VC version by Jason Avinger, see 
        http://www.damtp.cam.ac.uk/user/kp229/tree/
   for the original.
  	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
	
*/
  #ifndef tree_hh_
#define tree_hh_
  #include <cassert>
#include <memory>
#include <stdexcept>
#include <iterator>
#include <set>
  #ifdef _MSC_VER // MSVC does not have HP style construct/destroy 
template <class T1, class T2>
inline void constructor(T1* p, T2& val) 
 {
 new ((void *) p) T1(val);
 }
  template <class T1>
inline void constructor(T1* p) 
 {
 new ((void *) p) T1;
 }
  template <class T1>
inline void destructor(T1* p)
 {
 p->~T1();
 }
#else
   #define constructor std::construct
   #define destructor  std::destroy
#endif
  
template<class T>
struct tree_node_ {
		tree_node_<T> *parent;
	   tree_node_<T> *first_child, *last_child;
		tree_node_<T> *prev_sibling, *next_sibling;
		T data;
};
  template <class T, class tree_node_allocator = std::allocator<tree_node_<T> > >
class tree {
	protected:
		typedef tree_node_<T> tree_node;
	public:
		typedef T value_type;
  		class iterator;
		class sibling_iterator;
  		tree()
		{
		head_initialise_();
		}
		~tree()
		{
		clear();
		alloc_.deallocate(head,1);
		}
		tree(const tree<T, tree_node_allocator>& other)
		{
		head_initialise_();
		copy_(other);
		}
		void operator=(const tree<T, tree_node_allocator>& other)
		{
		copy_(other);
		}
  		class iterator { 
			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()
				: node(0), skip_current_children_(false)
				{
				}
  				iterator(tree_node *tn)
				: node(tn), skip_current_children_(false)
				{
				}
  				iterator(const sibling_iterator& other)
				: node(other.node), skip_current_children_(false)
				{
				if(node==0) {
					node=other.range_last();
					skip_children();
					increment_();
					}
				}
  				iterator&  operator++(void)
				{
				if(!increment_()) {
					node=0;
					}
				return *this;
				}
  				iterator&  operator--(void)
				{
				if(!decrement_()) {
					node=0;
					}
				return *this;
				}
  				iterator&  operator+=(unsigned int num)
				{
				while(num>0) {
					++(*this);
					--num;
					}
				return (*this);
				}
  				iterator&  operator-=(unsigned int num)
				{
				while(num>0) {
					--(*this);
					--num;
					}
				return (*this);
				}
  				T&         operator*(void) const
				{
				return node->data;
				}
  				T*         operator->(void) const
				{
				return &(node->data);
				}
  				bool       operator==(const iterator& other) const
				{
				if(other.node==node) return true;
				else return false;
				}
  				bool       operator!=(const iterator& other) const
				{
				if(other.node!=node) return true;
				else return false;
				}
  				iterator   operator+(int num) const
				{
				iterator ret(*this);
				while(num>0) {
					++ret;
					--num;
					}
				return ret;
				}
  				sibling_iterator begin() const
				{
				sibling_iterator ret(node->first_child);
				ret.parent_=node;
				return ret;
				}
  				sibling_iterator end() const
				{
				sibling_iterator ret(0);
				ret.parent_=node;
				return ret;
				}
  				// do not iterate over children of this node
				void skip_children() 
				{
				skip_current_children_=true;
				}
  				bool is_valid() const
				{
				if(node==0) return false;
				else return true;
				}
  				unsigned int 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;
				}
  				tree_node *node;
			private:
				bool increment_()
				{
				assert(node!=0);
				if(!skip_current_children_ && node->first_child != 0) {
					node=node->first_child;
					return true;
					}
				else {
					skip_current_children_=false;
					while(node->next_sibling==0) {
						node=node->parent;
						if(node==0)
							return false;
						}
					node=node->next_sibling;
					return true;
					}
				}
  				bool decrement_()
				{
				assert(node!=0);
				if(node->parent==0) {
					if(node->last_child==0)
						node=node->prev_sibling;
					while(node->last_child)
						node=node->last_child;
					if(!node) return false;
					}
				else {
					if(node->prev_sibling) {
						if(node->prev_sibling->last_child) {
							node=node->prev_sibling->last_child;
							}
						else {
							node=node->prev_sibling;
							}
						}
					else {
						node=node->parent;
						if(node==0)
							return false;
						}
					}
				return true;
				}
  				bool skip_current_children_;
		};
  		class sibling_iterator {
				friend class tree<T, tree_node_allocator>;
				//friend class tree<T, tree_node_allocator>::iterator;
			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;
  				sibling_iterator()
				: node(0), parent_(0)
				{
				}
  				sibling_iterator(tree_node *tn)
				: node(tn)
				{
				set_parent_();
				}
  				sibling_iterator(const sibling_iterator& other)
				: node(other.node), parent_(other.parent_)
				{
				}
  				sibling_iterator(const iterator& other)
				: node(other.node)
				{
				set_parent_();
				}
  				sibling_iterator&  operator++(void)
				{
				if(node)
					node=node->next_sibling;
				return *this;
				}
  				sibling_iterator&  operator--(void)
				{
				if(node) node=node->prev_sibling;
				else {
					assert(parent_);
					node=parent_->last_child;
					}
				return *this;
				}
  				sibling_iterator&  operator+=(unsigned int num)
				{
				while(num>0) {
					++(*this);
					--num;
					}
				return (*this);
				}
  				sibling_iterator&  operator-=(unsigned int num)
				{
				while(num>0) {
					--(*this);
					--num;
					}
				return (*this);
				}
  				T&                 operator*(void) const
				{
				return node->data;
				}
  				T*                 operator->(void) const
				{
				return &(node->data);
				}
  				bool               operator==(const sibling_iterator& other) const
				{
				if(other.node==node) return true;
				else return false;
				}
  				bool               operator!=(const sibling_iterator& other) const
				{
				if(other.node!=node) return true;
				else return false;
				}
  				sibling_iterator   operator+(int num) const
				{
				sibling_iterator ret(*this);
				while(num>0) {
					++ret;
					--num;
					}
				return ret;
				}
  
				bool       is_valid() const
				{
				if(node==0) return false;
				else return true;
				}
  				tree_node *range_first() const
				{
				tree_node *tmp=parent_->first_child;
				return tmp;
				}
  				tree_node *range_last() const
				{
				return parent_->last_child;
				}
  				tree_node *node;
  
			private:
				void set_parent_()
				{
				parent_=0;
				if(node==0) return;
				if(node->parent!=0)
					parent_=node->parent;
				}
  				tree_node *parent_;
		};
  		// begin/end of tree
		iterator begin() const
		{
		return iterator(head->next_sibling);
		}
		iterator end() const
		{
		return iterator(head);
		}
		// begin/end of children of node
		sibling_iterator begin(iterator pos) const
		{
		if(pos.node->first_child==0) {
			return end(pos);
			}
		return pos.node->first_child;
		}
  		sibling_iterator end(iterator pos) const
		{
		sibling_iterator ret(0);
		ret.parent_= pos.node;
		return ret;
		}
  		iterator parent(iterator position) const
		{
		assert(position.node!=0);
		return iterator(position.node->parent);
		}
  		iterator previous_sibling(iterator position) const
		{
		assert(position.node!=0);
		return iterator(position.node->prev_sibling);
		}
  		iterator next_sibling(iterator position) const
		{
		assert(position.node!=0);
		return iterator(position.node->next_sibling);
		}
  		void clear()
		{
		if(head)
			while(head->next_sibling!=head)
				erase(head->next_sibling);
		}
  		// erase element at position pointed to by iterator, increment iterator
		iterator erase(iterator it)
		{
		tree_node *cur=it.node;
		assert(cur!=head);
		iterator 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;
			}
  		destructor(&cur->data);
		alloc_.deallocate(cur,1);
		return ret;
		}
		// erase all children of the node pointed to by iterator
		void     erase_children(iterator it)
		{
		tree_node *cur=it.node->first_child;
		tree_node *prev=0;
  		while(cur!=0) {
			prev=cur;
			cur=cur->next_sibling;
			erase_children(prev);
			destructor(&prev->data);
			alloc_.deallocate(prev,1);
			}
		it.node->first_child=0;
		it.node->last_child=0;
		}
  		// insert node as last child of node pointed to by position
		iterator append_child(iterator position)
 		{
		assert(position.node!=head);
  		tree_node* tmp = alloc_.allocate(1,0);
		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;
 		} 
  		iterator append_child(iterator 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);
		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;
		}
  		iterator append_child(iterator position, iterator other_position)
		{
		assert(position.node!=head);
  		sibling_iterator aargh=append_child(position, value_type());
		return replace(aargh, aargh+1, other, sibling_iterator(other)+1);
		}
  		// short-hand to insert topmost node in otherwise empty tree
		iterator set_head(const T& x)
		{
		assert(begin()==end());
		return insert(begin(), x);
		}
  		// insert node as previous sibling of node pointed to by position
		iterator insert(iterator position, const T& x)
		{
		tree_node* tmp = alloc_.allocate(1,0);
		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)
			tmp->parent->first_child=tmp;
		else
			tmp->prev_sibling->next_sibling=tmp;
		return tmp;
		}
  		// insert node as previous sibling of node pointed to by position
		iterator insert(sibling_iterator position, const T& x)
		{
		tree_node* tmp = alloc_.allocate(1,0);
		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();
			}
		else {
			tmp->parent=position.node->parent;
			tmp->prev_sibling=position.node->prev_sibling;
			position.node->prev_sibling=tmp;
			}
  		if(tmp->prev_sibling==0)
			tmp->parent->first_child=tmp;
		else
			tmp->prev_sibling->next_sibling=tmp;
		return tmp;
		}
  		// insert node (with children) pointed to by subtree as previous sibling of node pointed to by position
		iterator insert(iterator position, iterator subtree)
		{
		// insert dummy
		iterator it=insert(position, value_type());
		// replace dummy with subtree
		return replace(it, subtree);
		}
  		// insert node (with children) pointed to by subtree as previous sibling of node pointed to by position
		iterator insert(sibling_iterator position, iterator subtree)
		{
		// insert dummy
		iterator it=insert(position, value_type());
		// replace dummy with subtree
		return replace(it, subtree);
		}
  		// insert node as next sibling of node pointed to by position
		iterator insert_after(iterator position, const T& x)
		{
		tree_node* tmp = alloc_.allocate(1,0);
		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) {
			tmp->parent->last_child=tmp;
			}
		return tmp;
		}
  
		// replace node at 'position' with other node (keeping same children)
		iterator replace(iterator position, const T& x)
		{
		destructor(&position.node->data);
		constructor(&position.node->data, x);
		return position;
		}
  		// replace node at 'position' with subtree starting at 'from' (do not erase subtree at 'from')
		iterator replace(iterator position, iterator from)
		{
		assert(position.node!=head);
  		tree_node *current_from=from.node;
		tree_node *start_from=from.node;
		tree_node *last=from.node->next_sibling;
		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);
		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;
		destructor(¤t_to->data);
		alloc_.deallocate(current_to,1);
		current_to=tmp;
  		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;
		}
  		// replace string of siblings (plus their children) with copy of a new string (with children)
		iterator 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;
		iterator ret;
		while(1==1) {
			iterator tt=insert(iterator(orig_first), 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(orig_first);
			if(last) 
				break;
			orig_first=next;
			}
		return ret;
		}
 
  		// move all children of node at 'position' to be siblings
		iterator flatten(iterator 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;
		}
  		// move nodes in range to be children of 'position'
		iterator reparent(iterator position, sibling_iterator begin, sibling_iterator end)
		{
		tree_node *first=begin.node;
		tree_node *last=first;
		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;
		}
  		// ditto, the range being all children of the 'from' node
		iterator reparent(iterator position, iterator from)
		{
		if(from.node->first_child==0) return position;
		return reparent(position, from.node->first_child, from.node->last_child);
		}
  		// merge with other tree, creating new branches and leaves only if they are not already present
		void     merge(iterator position, iterator other, bool duplicate_leaves=false)
		{
		sibling_iterator fnd;
		sibling_iterator oit=other;
		while(oit.is_valid()) {
			if((fnd=find(position.begin(), position.end(), (*other)))!=position.end()) {
				if(duplicate_leaves && other.begin()==other.end()) { // it's a leave
					append_child(position, (*other));
					}
				else {
					if(other.begin()!=other.end())
						merge(fnd, other.begin(), duplicate_leaves);
					}
				}
			else {
				insert(position.end(), oit);
				}
			++oit;
			}
		}
  		// 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)
		{
		std::less<T> comp;
		sort(from, to, comp, deep);
		}
  		template<class StrictWeakOrdering>
		void     sort(sibling_iterator from, sibling_iterator to, StrictWeakOrdering comp, bool deep=false)
		{
		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<tree_node *, compare_nodes<StrictWeakOrdering> > nodes;
		sibling_iterator it=from, it2=to;
		while(it != to) {
			nodes.insert(it.node);
			++it;
			}
		// reassemble
		--it2;
		tree_node *prev=from.node->prev_sibling;
		tree_node *next=it2.node->next_sibling;
		typename std::multiset<tree_node *, compare_nodes<StrictWeakOrdering> >::iterator nit=nodes.begin(), eit=nodes.end();
		if(prev==0) {
			(*nit)->parent->first_child=(*nit);
			}
		--eit;
		while(nit!=eit) {
			(*nit)->prev_sibling=prev;
			if(prev)
				prev->next_sibling=(*nit);
			prev=(*nit);
			++nit;
			}
		if(prev)
			prev->next_sibling=(*eit);
		(*eit)->next_sibling=next;
		if(next==0) {
			(*eit)->parent->last_child=next;
			}
  		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;
				}
			}
		}
  		// compare subtrees starting at the two iterators (compares nodes as well as tree structure)
		template<class BinaryPredicate>
		bool     equal(iterator one, iterator two, iterator three, BinaryPredicate fun) const
		{
		while(one!=two && three.is_valid()) {
			if(one.number_of_children()!=three.number_of_children()) 
				return false;
			if(!fun(*one,*three))
				return false;
			++one;
			++three;
			}
		return true;
		}
  		// extract a new tree formed by the range of siblings plus all their children
		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;
		}
  		void     subtree(tree&, sibling_iterator from, sibling_iterator to) const
		{
		tmp.set_head(value_type());
		tmp.replace(tmp.begin(), tmp.end(), from, to);
		}
		
		// count the total number of nodes
		int      size() const
		{
		int i=0;
		iterator it=begin(), eit=end();
		while(it!=eit) {
			++i;
			++it;
			}
		return i;
		}
  		// compute the depth to the root
		int      depth(iterator it) const
		{
		tree_node* pos=it.node;
		assert(pos!=0);
		int ret=0;
		while(pos->parent!=0) {
			pos=pos->parent;
			++ret;
			}
		return ret;
		}
  		// count the number of children of node at position
		unsigned int number_of_children(iterator 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;
			}
		return ret;
		}
  		// count the number of 'next' siblings of node at iterator
		unsigned int number_of_siblings(iterator it) const
		{
		tree_node *pos=it.node;
		unsigned int ret=1;
		while(pos->next_sibling && pos->next_sibling!=head) {
			++ret;
			pos=pos->next_sibling;
			}
		return ret;
		}
  		// determine whether node at position is in the subtrees with root in the range
		bool     is_in_subtree(iterator position, iterator begin, iterator end) const
		{
		// FIXME: this should be optimised.
		iterator tmp=begin;
		while(tmp!=end) {
			if(tmp==it) return true;
			++tmp;
			}
		return false;
		}
  		// return the n-th child of the node at position
		T&       child(iterator position, unsigned int) const
		{
		tree_node *tmp=it.node->first_child;
		while(num--) {
			assert(tmp!=0);
			tmp=tmp->next_sibling;
			}
		return tmp->data;
		}
  	private:
		tree_node_allocator alloc_;
		tree_node *head;    // head is always a dummy; if an iterator points to head it is invalid
		void head_initialise_()
		{ 
		head = alloc_.allocate(1,0); // MSVC does not have default second argument 
		head->parent=0;
		head->first_child=0;
		head->last_child=0;
		head->prev_sibling=head;
		head->next_sibling=head;
		}
  		void copy_(const tree<T, tree_node_allocator>& other)
		{
		clear();
		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<class StrictWeakOrdering>
		class compare_nodes {
			public:
				bool operator()(const tree_node* a, const tree_node* b)
				{
				static StrictWeakOrdering comp;
				return comp(a->data, b->data);
				}
		};
};
  #endif
  // Local variables:
// default-tab-width: 3
// End:
   |