Main Page | Class Hierarchy | Data Structures | File List | Data Fields | Globals

tree.hh

00001 /* 
00002 
00003    $Id: tree.hh,v 1.1 2002/10/17 20:04:35 benoitg Exp $
00004 
00005         STL-like templated tree class.
00006         Copyright (C) 2001  Kasper Peeters <k.peeters@damtp.cam.ac.uk>
00007 
00008    See 
00009   
00010       http://www.damtp.cam.ac.uk/user/kp229/tree/
00011 
00012    for more information and documentation. See the Changelog file for
00013         other credits.
00014 
00015         This program is free software; you can redistribute it and/or modify
00016         it under the terms of the GNU General Public License as published by
00017         the Free Software Foundation; version 2.
00018         
00019         This program is distributed in the hope that it will be useful,
00020         but WITHOUT ANY WARRANTY; without even the implied warranty of
00021         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022         GNU General Public License for more details.
00023         
00024         You should have received a copy of the GNU General Public License
00025         along with this program; if not, write to the Free Software
00026         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027         
00028 */
00029 
00030 #ifndef tree_hh_
00031 #define tree_hh_
00032 
00033 #include <cassert>
00034 #include <memory>
00035 #include <stdexcept>
00036 #include <iterator>
00037 #include <set>
00038 
00039 // HP-style construct/destroy have gone from the standard,
00040 // so here is a copy.
00041 
00042 template <class T1, class T2>
00043 inline void constructor(T1* p, T2& val) 
00044         {
00045         new ((void *) p) T1(val);
00046         }
00047 
00048 template <class T1>
00049 inline void constructor(T1* p) 
00050         {
00051         new ((void *) p) T1;
00052         }
00053 
00054 template <class T1>
00055 inline void destructor(T1* p)
00056         {
00057         p->~T1();
00058         }
00059 
00060 
00061 template<class T>
00062 struct tree_node_ {
00063                 tree_node_<T> *parent;
00064            tree_node_<T> *first_child, *last_child;
00065                 tree_node_<T> *prev_sibling, *next_sibling;
00066                 T data;
00067 };
00068 
00069 template <class T, class tree_node_allocator = std::allocator<tree_node_<T> > >
00070 class tree {
00071         protected:
00072                 typedef tree_node_<T> tree_node;
00073         public:
00074                 typedef T value_type;
00075 
00076                 class iterator;
00077                 class sibling_iterator;
00078 
00079                 tree();
00080                 tree(const T&);
00081                 tree(iterator);
00082                 tree(const tree<T, tree_node_allocator>&);
00083                 ~tree();
00084                 void operator=(const tree<T, tree_node_allocator>&);
00085 
00086                 class iterator { 
00087                         public:
00088                                 typedef T                          value_type;
00089                                 typedef T*                         pointer;
00090                                 typedef T&                         reference;
00091                                 typedef size_t                     size_type;
00092                                 typedef ptrdiff_t                  difference_type;
00093                                 typedef std::bidirectional_iterator_tag iterator_category;
00094 
00095                                 iterator();
00096                                 iterator(tree_node *);
00097                                 iterator(const sibling_iterator&);
00098 
00099                                 iterator&  operator++(void);
00100                            iterator&  operator--(void);
00101                                 iterator&  operator+=(unsigned int);
00102                                 iterator&  operator-=(unsigned int);
00103                                 T&         operator*(void) const;
00104                                 T*         operator->(void) const;
00105                                 bool       operator==(const iterator&) const;
00106                                 bool       operator!=(const iterator&) const;
00107                                 iterator   operator+(int) const;
00108 
00109                                 sibling_iterator begin() const;
00110                                 sibling_iterator end() const;
00111 
00112                                 void skip_children(); // do not iterate over children of this node
00113                                 bool is_valid() const;
00114                                 unsigned int number_of_children() const;
00115 
00116                                 tree_node *node;
00117                         private:
00118                                 bool increment_();
00119                                 bool decrement_();
00120                                 bool skip_current_children_;
00121                 };
00122 
00123                 class sibling_iterator {
00124                         public:
00125                                 typedef T                          value_type;
00126                                 typedef T*                         pointer;
00127                                 typedef T&                         reference;
00128                                 typedef size_t                     size_type;
00129                                 typedef ptrdiff_t                  difference_type;
00130                                 typedef std::bidirectional_iterator_tag iterator_category;
00131 
00132                                 sibling_iterator();
00133                                 sibling_iterator(tree_node *);
00134                                 sibling_iterator(const sibling_iterator&);
00135                                 sibling_iterator(const iterator&);
00136 
00137                                 sibling_iterator&  operator++(void);
00138                                 sibling_iterator&  operator--(void);
00139                                 sibling_iterator&  operator+=(unsigned int);
00140                                 sibling_iterator&  operator-=(unsigned int);
00141                                 T&                 operator*(void) const;
00142                                 T*                 operator->(void) const;
00143                                 bool               operator==(const sibling_iterator&) const;
00144                                 bool               operator!=(const sibling_iterator&) const;
00145                                 sibling_iterator   operator+(int) const;
00146 
00147                                 bool       is_valid() const;
00148                                 tree_node *range_first() const;
00149                                 tree_node *range_last() const;
00150 
00151                                 tree_node *node;
00152 
00153                                 friend class tree<T, tree_node_allocator>;
00154                                 friend class tree<T, tree_node_allocator>::iterator;
00155                         private:
00156                                 void set_parent_();
00157                                 tree_node *parent_;
00158                 };
00159 
00160                 // begin/end of tree
00161                 iterator begin() const;
00162                 iterator end() const;
00163                 // begin/end of children of node
00164                 sibling_iterator begin(iterator) const;
00165                 sibling_iterator end(iterator) const;
00166                 iterator parent(iterator) const;
00167                 iterator previous_sibling(iterator) const;
00168                 iterator next_sibling(iterator) const;
00169                 void     clear();
00170                 // erase element at position pointed to by iterator, increment iterator
00171                 iterator erase(iterator);
00172                 // erase all children of the node pointed to by iterator
00173                 void     erase_children(iterator);
00174 
00175                 // insert node as last child of node pointed to by position
00176                 iterator append_child(iterator position); 
00177                 iterator append_child(iterator position, const T& x);
00178                 iterator append_child(iterator position, iterator other_position);
00179 
00180                 // short-hand to insert topmost node in otherwise empty tree
00181                 iterator set_head(const T& x);
00182                 // insert node as previous sibling of node pointed to by position
00183                 iterator insert(iterator position, const T& x);
00184                 // insert node as previous sibling of node pointed to by position
00185                 iterator insert(sibling_iterator position, const T& x);
00186                 // insert node (with children) pointed to by subtree as previous sibling of node pointed to by position
00187                 iterator insert(iterator position, iterator subtree);
00188                 // insert node (with children) pointed to by subtree as previous sibling of node pointed to by position
00189                 iterator insert(sibling_iterator position, iterator subtree);
00190                 // insert node as next sibling of node pointed to by position
00191                 iterator insert_after(iterator position, const T& x);
00192 
00193                 // replace node at 'position' with other node (keeping same children); 'position' becomes invalid.
00194                 iterator replace(iterator position, const T& x);
00195                 // replace node at 'position' with subtree starting at 'from' (do not erase subtree at 'from'); see above.
00196                 iterator replace(iterator position, iterator from);
00197                 // replace string of siblings (plus their children) with copy of a new string (with children); see above
00198                 iterator replace(sibling_iterator orig_begin, sibling_iterator orig_end, 
00199                                                           sibling_iterator new_begin,  sibling_iterator new_end); 
00200 
00201                 // move all children of node at 'position' to be siblings, returns position
00202                 iterator flatten(iterator position);
00203                 // move nodes in range to be children of 'position'
00204                 iterator reparent(iterator position, sibling_iterator begin, sibling_iterator end);
00205                 // ditto, the range being all children of the 'from' node
00206                 iterator reparent(iterator position, iterator from);
00207                 // merge with other tree, creating new branches and leaves only if they are not already present
00208                 void     merge(iterator position, iterator other, bool duplicate_leaves=false);
00209                 // sort (std::sort only moves values of nodes, this one moves children as well)
00210                 void     sort(sibling_iterator from, sibling_iterator to, bool deep=false);
00211                 template<class StrictWeakOrdering>
00212                 void     sort(sibling_iterator from, sibling_iterator to, StrictWeakOrdering comp, bool deep=false);
00213                 // compare two ranges of nodes (compares nodes as well as tree structure)
00214                 template<class BinaryPredicate>
00215                 bool     equal(iterator one, iterator two, iterator three, BinaryPredicate) const;
00216                 // extract a new tree formed by the range of siblings plus all their children
00217                 tree     subtree(sibling_iterator from, sibling_iterator to) const;
00218                 void     subtree(tree&, sibling_iterator from, sibling_iterator to) const;
00219                 // exchange the node (plus subtree) with its sibling node (do nothing if no sibling present)
00220                 void     swap(sibling_iterator it);
00221                 
00222                 // count the total number of nodes
00223                 int      size() const;
00224                 // compute the depth to the root
00225                 int      depth(iterator) const;
00226                 // count the number of children of node at position
00227                 unsigned int number_of_children(iterator) const;
00228                 // count the number of 'next' siblings of node at iterator
00229                 unsigned int number_of_siblings(iterator) const;
00230                 // determine whether node at position is in the subtrees with root in the range
00231                 bool     is_in_subtree(iterator position, iterator begin, iterator end) const;
00232 
00233                 // return the n-th child of the node at position
00234                 T&       child(iterator position, unsigned int) const;
00235         private:
00236                 tree_node_allocator alloc_;
00237                 tree_node *head;    // head is always a dummy; if an iterator points to head it is invalid
00238                 void head_initialise_();
00239                 void copy_(const tree<T, tree_node_allocator>& other);
00240                 template<class StrictWeakOrdering>
00241                 class compare_nodes {
00242                         public:
00243                                 bool operator()(const tree_node*, const tree_node *);
00244                 };
00245 };
00246 
00247 
00248 
00249 // Tree
00250 
00251 template <class T, class tree_node_allocator>
00252 tree<T, tree_node_allocator>::tree() 
00253         {
00254         head_initialise_();
00255         }
00256 
00257 template <class T, class tree_node_allocator>
00258 tree<T, tree_node_allocator>::tree(const T& x) 
00259         {
00260         head_initialise_();
00261         set_head(x);
00262         }
00263 
00264 template <class T, class tree_node_allocator>
00265 tree<T, tree_node_allocator>::tree(iterator other)
00266         {
00267         head_initialise_();
00268         set_head((*other));
00269         replace(begin(), other);
00270         }
00271 
00272 template <class T, class tree_node_allocator>
00273 tree<T, tree_node_allocator>::~tree()
00274         {
00275         clear();
00276         alloc_.deallocate(head,1);
00277         }
00278 
00279 template <class T, class tree_node_allocator>
00280 void tree<T, tree_node_allocator>::head_initialise_() 
00281    { 
00282    head = alloc_.allocate(1,0); // MSVC does not have default second argument 
00283 
00284    head->parent=0;
00285    head->first_child=0;
00286    head->last_child=0;
00287    head->prev_sibling=head;
00288    head->next_sibling=head;
00289    }
00290 
00291 template <class T, class tree_node_allocator>
00292 void tree<T, tree_node_allocator>::operator=(const tree<T, tree_node_allocator>& other)
00293         {
00294         copy_(other);
00295         }
00296 
00297 template <class T, class tree_node_allocator>
00298 tree<T, tree_node_allocator>::tree(const tree<T, tree_node_allocator>& other)
00299         {
00300         head_initialise_();
00301         copy_(other);
00302         }
00303 
00304 template <class T, class tree_node_allocator>
00305 void tree<T, tree_node_allocator>::copy_(const tree<T, tree_node_allocator>& other) 
00306         {
00307         clear();
00308         iterator it=other.begin(), to=begin();
00309         while(it!=other.end()) {
00310                 to=insert(to, (*it));
00311                 it.skip_children();
00312                 ++it;
00313                 }
00314         to=begin();
00315         it=other.begin();
00316         while(it!=other.end()) {
00317                 to=replace(to, it);
00318                 to.skip_children();
00319                 it.skip_children();
00320                 ++to;
00321                 ++it;
00322                 }
00323         }
00324 
00325 template <class T, class tree_node_allocator>
00326 void tree<T, tree_node_allocator>::clear()
00327         {
00328         if(head)
00329                 while(head->next_sibling!=head)
00330                         erase(head->next_sibling);
00331         }
00332 
00333 template<class T, class tree_node_allocator> 
00334 void tree<T, tree_node_allocator>::erase_children(iterator it)
00335         {
00336         tree_node *cur=it.node->first_child;
00337         tree_node *prev=0;
00338 
00339         while(cur!=0) {
00340                 prev=cur;
00341                 cur=cur->next_sibling;
00342                 erase_children(prev);
00343                 destructor(&prev->data);
00344                 alloc_.deallocate(prev,1);
00345                 }
00346         it.node->first_child=0;
00347         it.node->last_child=0;
00348         }
00349 
00350 template<class T, class tree_node_allocator> 
00351 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::erase(iterator it)
00352         {
00353         tree_node *cur=it.node;
00354         assert(cur!=head);
00355         iterator ret=it;
00356         ret.skip_children();
00357         ++ret;
00358         erase_children(it);
00359         if(cur->prev_sibling==0) {
00360                 cur->parent->first_child=cur->next_sibling;
00361                 }
00362         else {
00363                 cur->prev_sibling->next_sibling=cur->next_sibling;
00364                 }
00365         if(cur->next_sibling==0) {
00366                 cur->parent->last_child=cur->prev_sibling;
00367                 }
00368         else {
00369                 cur->next_sibling->prev_sibling=cur->prev_sibling;
00370                 }
00371 
00372         destructor(&cur->data);
00373    alloc_.deallocate(cur,1);
00374         return ret;
00375         }
00376 
00377 template <class T, class tree_node_allocator>
00378 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::begin() const
00379         {
00380         return iterator(head->next_sibling);
00381         }
00382 
00383 template <class T, class tree_node_allocator>
00384 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::end() const
00385         {
00386         return iterator(head);
00387         }
00388 
00389 template <class T, class tree_node_allocator>
00390 typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::begin(iterator pos) const
00391         {
00392         if(pos.node->first_child==0) {
00393                 return end(pos);
00394                 }
00395         return pos.node->first_child;
00396         }
00397 
00398 template <class T, class tree_node_allocator>
00399 typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::end(iterator pos) const
00400         {
00401         sibling_iterator ret(0);
00402         ret.parent_=pos.node;
00403         return ret;
00404         }
00405 
00406 template <class T, class tree_node_allocator>
00407 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::parent(iterator position) const
00408         {
00409         assert(position.node!=0);
00410         return iterator(position.node->parent);
00411         }
00412 
00413 template <class T, class tree_node_allocator>
00414 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::previous_sibling(iterator position) const
00415         {
00416         assert(position.node!=0);
00417         return iterator(position.node->prev_sibling);
00418         }
00419 
00420 template <class T, class tree_node_allocator>
00421 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::next_sibling(iterator position) const
00422         {
00423         assert(position.node!=0);
00424         if(position.node->next_sibling==0)
00425                 return end(position.node->parent);
00426         else
00427                 return iterator(position.node->next_sibling);
00428         }
00429 
00430 template <class T, class tree_node_allocator>
00431 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::append_child(iterator position)
00432         {
00433         assert(position.node!=head);
00434 
00435         tree_node* tmp = alloc_.allocate(1,0);
00436         constructor(&tmp->data);
00437         tmp->first_child=0;
00438         tmp->last_child=0;
00439 
00440         tmp->parent=position.node;
00441         if(position.node->last_child!=0) {
00442                 position.node->last_child->next_sibling=tmp;
00443                 }
00444         else {
00445                 position.node->first_child=tmp;
00446                 }
00447         tmp->prev_sibling=position.node->last_child;
00448         position.node->last_child=tmp;
00449         tmp->next_sibling=0;
00450         return tmp;
00451         }
00452 
00453 template <class T, class tree_node_allocator>
00454 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::append_child(iterator position, const T& x)
00455         {
00456         // If your program fails here you probably used 'append_child' to add the top
00457         // node to an empty tree. From version 1.45 the top element should be added
00458         // using 'insert'. See the documentation for further information, and sorry about
00459         // the API change.
00460         assert(position.node!=head);
00461 
00462         tree_node* tmp = alloc_.allocate(1,0);
00463         constructor(&tmp->data, x);
00464         tmp->first_child=0;
00465         tmp->last_child=0;
00466 
00467         tmp->parent=position.node;
00468         if(position.node->last_child!=0) {
00469                 position.node->last_child->next_sibling=tmp;
00470                 }
00471         else {
00472                 position.node->first_child=tmp;
00473                 }
00474         tmp->prev_sibling=position.node->last_child;
00475         position.node->last_child=tmp;
00476         tmp->next_sibling=0;
00477         return tmp;
00478         }
00479 
00480 template <class T, class tree_node_allocator>
00481 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::append_child(iterator position, iterator other)
00482         {
00483         assert(position.node!=head);
00484 
00485         sibling_iterator aargh=append_child(position, value_type());
00486         return replace(aargh, aargh+1, other, sibling_iterator(other)+1);
00487         }
00488 
00489 template <class T, class tree_node_allocator>
00490 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::set_head(const T& x)
00491         {
00492         assert(begin()==end());
00493         return insert(begin(), x);
00494         }
00495 
00496 template <class T, class tree_node_allocator>
00497 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::insert(iterator position, const T& x)
00498         {
00499         tree_node* tmp = alloc_.allocate(1,0);
00500         constructor(&tmp->data, x);
00501         tmp->first_child=0;
00502         tmp->last_child=0;
00503 
00504         tmp->parent=position.node->parent;
00505         tmp->next_sibling=position.node;
00506         tmp->prev_sibling=position.node->prev_sibling;
00507         position.node->prev_sibling=tmp;
00508 
00509         if(tmp->prev_sibling==0)
00510                 tmp->parent->first_child=tmp;
00511         else
00512                 tmp->prev_sibling->next_sibling=tmp;
00513         return tmp;
00514         }
00515 
00516 template <class T, class tree_node_allocator>
00517 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::insert(sibling_iterator position, const T& x)
00518         {
00519         tree_node* tmp = alloc_.allocate(1,0);
00520         constructor(&tmp->data, x);
00521         tmp->first_child=0;
00522         tmp->last_child=0;
00523 
00524         tmp->next_sibling=position.node;
00525         if(position.node==0) { // iterator points to end of a subtree
00526                 tmp->parent=position.parent_;
00527                 tmp->prev_sibling=position.range_last();
00528                 }
00529         else {
00530                 tmp->parent=position.node->parent;
00531                 tmp->prev_sibling=position.node->prev_sibling;
00532                 position.node->prev_sibling=tmp;
00533                 }
00534 
00535         if(tmp->prev_sibling==0)
00536                 tmp->parent->first_child=tmp;
00537         else
00538                 tmp->prev_sibling->next_sibling=tmp;
00539         return tmp;
00540         }
00541 
00542 template <class T, class tree_node_allocator>
00543 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::insert_after(iterator position, const T& x)
00544         {
00545         tree_node* tmp = alloc_.allocate(1,0);
00546         constructor(&tmp->data, x);
00547         tmp->first_child=0;
00548         tmp->last_child=0;
00549 
00550         tmp->parent=position.node->parent;
00551         tmp->prev_sibling=position.node;
00552         tmp->next_sibling=position.node->next_sibling;
00553         position.node->next_sibling=tmp;
00554 
00555         if(tmp->next_sibling==0) {
00556                 tmp->parent->last_child=tmp;
00557                 }
00558         else {
00559                 tmp->next_sibling->prev_sibling=tmp;
00560                 }
00561         return tmp;
00562         }
00563 
00564 template <class T, class tree_node_allocator>
00565 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::insert(iterator position, iterator subtree)
00566         {
00567         // insert dummy
00568         iterator it=insert(position, value_type());
00569         // replace dummy with subtree
00570         return replace(it, subtree);
00571         }
00572 
00573 template <class T, class tree_node_allocator>
00574 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::insert(sibling_iterator position, iterator subtree)
00575         {
00576         // insert dummy
00577         iterator it=insert(position, value_type());
00578         // replace dummy with subtree
00579         return replace(it, subtree);
00580         }
00581 
00582 template <class T, class tree_node_allocator>
00583 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::replace(iterator position, const T& x)
00584         {
00585         destructor(&position.node->data);
00586         constructor(&position.node->data, x);
00587         return position;
00588         }
00589 
00590 template <class T, class tree_node_allocator>
00591 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::replace(iterator position, iterator from)
00592         {
00593         assert(position.node!=head);
00594 
00595         tree_node *current_from=from.node;
00596         tree_node *start_from=from.node;
00597         tree_node *last=from.node->next_sibling;
00598         tree_node *current_to  =position.node;
00599 
00600         // replace the node at position with head of the replacement tree at from
00601         erase_children(position);       
00602         tree_node* tmp = alloc_.allocate(1,0);
00603         constructor(&tmp->data, (*from));
00604         tmp->first_child=0;
00605         tmp->last_child=0;
00606         if(current_to->prev_sibling==0) {
00607                 current_to->parent->first_child=tmp;
00608                 }
00609         else {
00610                 current_to->prev_sibling->next_sibling=tmp;
00611                 }
00612         tmp->prev_sibling=current_to->prev_sibling;
00613         if(current_to->next_sibling==0) {
00614                 current_to->parent->last_child=tmp;
00615                 }
00616         else {
00617                 current_to->next_sibling->prev_sibling=tmp;
00618                 }
00619         tmp->next_sibling=current_to->next_sibling;
00620         tmp->parent=current_to->parent;
00621         destructor(&current_to->data);
00622         alloc_.deallocate(current_to,1);
00623         current_to=tmp;
00624 
00625         iterator toit=tmp;
00626 
00627         // copy all children
00628         do {
00629                 assert(current_from!=0);
00630                 if(current_from->first_child != 0) {
00631                         current_from=current_from->first_child;
00632                         toit=append_child(toit, current_from->data);
00633                         }
00634                 else {
00635                         while(current_from->next_sibling==0 && current_from!=start_from) {
00636                                 current_from=current_from->parent;
00637                                 toit=parent(toit);
00638                                 assert(current_from!=0);
00639                                 }
00640                         current_from=current_from->next_sibling;
00641                         if(current_from!=last) {
00642                                 toit=append_child(parent(toit), current_from->data);
00643                                 }
00644                         }
00645                 } while(current_from!=last);
00646 
00647         return current_to;
00648         }
00649 
00650 template <class T, class tree_node_allocator>
00651 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::replace(sibling_iterator orig_begin, 
00652                                                                                                                                                                                                                                   sibling_iterator orig_end, 
00653                                                                                                                                                                                                                                   sibling_iterator new_begin, 
00654                                                                                                                                                                                                                                   sibling_iterator new_end)
00655         {
00656         tree_node *orig_first=orig_begin.node;
00657         tree_node *new_first=new_begin.node;
00658         tree_node *orig_last=orig_first;
00659         while(++orig_begin!=orig_end)
00660                 orig_last=orig_last->next_sibling;
00661         tree_node *new_last=new_first;
00662         while(++new_begin!=new_end)
00663                 new_last=new_last->next_sibling;
00664 
00665         // insert all siblings in new_first..new_last before orig_first
00666         bool first=true;
00667         iterator ret;
00668         while(1==1) {
00669                 iterator tt=insert(iterator(orig_first), new_first);
00670                 if(first) {
00671                         ret=tt;
00672                         first=false;
00673                         }
00674                 if(new_first==new_last)
00675                         break;
00676                 new_first=new_first->next_sibling;
00677                 }
00678 
00679         // erase old range of siblings
00680         bool last=false;
00681         tree_node *next=orig_first;
00682         while(1==1) {
00683                 if(next==orig_last) 
00684                         last=true;
00685                 next=next->next_sibling;
00686                 erase(orig_first);
00687                 if(last) 
00688                         break;
00689                 orig_first=next;
00690                 }
00691         return ret;
00692         }
00693 
00694 template <class T, class tree_node_allocator>
00695 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::flatten(iterator position)
00696         {
00697         if(position.node->first_child==0)
00698                 return position;
00699 
00700         tree_node *tmp=position.node->first_child;
00701         while(tmp) {
00702                 tmp->parent=position.node->parent;
00703                 tmp=tmp->next_sibling;
00704                 } 
00705         if(position.node->next_sibling) {
00706                 position.node->last_child->next_sibling=position.node->next_sibling;
00707                 position.node->next_sibling->prev_sibling=position.node->last_child;
00708                 }
00709         else {
00710                 position.node->parent->last_child=position.node->last_child;
00711                 }
00712         position.node->next_sibling=position.node->first_child;
00713         position.node->next_sibling->prev_sibling=position.node;
00714         position.node->first_child=0;
00715         position.node->last_child=0;
00716 
00717         return position;
00718         }
00719 
00720 
00721 template <class T, class tree_node_allocator>
00722 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::reparent(iterator position, sibling_iterator begin, 
00723                                                                                                                                   sibling_iterator end)
00724         {
00725         tree_node *first=begin.node;
00726         tree_node *last=first;
00727         if(begin==end) return begin;
00728         // determine last node
00729         while(++begin!=end) {
00730                 last=last->next_sibling;
00731                 }
00732         // move subtree
00733         if(first->prev_sibling==0) {
00734                 first->parent->first_child=last->next_sibling;
00735                 }
00736         else {
00737                 first->prev_sibling->next_sibling=last->next_sibling;
00738                 }
00739         if(last->next_sibling==0) {
00740                 last->parent->last_child=first->prev_sibling;
00741                 }
00742         else {
00743                 last->next_sibling->prev_sibling=first->prev_sibling;
00744                 }
00745         if(position.node->first_child==0) {
00746                 position.node->first_child=first;
00747                 position.node->last_child=last;
00748                 first->prev_sibling=0;
00749                 }
00750         else {
00751                 position.node->last_child->next_sibling=first;
00752                 first->prev_sibling=position.node->last_child;
00753                 position.node->last_child=last;
00754                 }
00755         last->next_sibling=0;
00756 
00757         tree_node *pos=first;
00758         while(1==1) {
00759                 pos->parent=position.node;
00760                 if(pos==last) break;
00761                 pos=pos->next_sibling;
00762                 }
00763 
00764         return first;
00765         }
00766 
00767 template <class T, class tree_node_allocator>
00768 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::reparent(iterator position, iterator from)
00769         {
00770         if(from.node->first_child==0) return position;
00771         return reparent(position, from.node->first_child, from.node->last_child);
00772         }
00773 
00774 template <class T, class tree_node_allocator>
00775 void tree<T, tree_node_allocator>::merge(iterator position, iterator other, bool duplicate_leaves)
00776         {
00777         sibling_iterator fnd;
00778         sibling_iterator oit=other;
00779         while(oit.is_valid()) {
00780                 if((fnd=find(position.begin(), position.end(), (*other)))!=position.end()) {
00781                         if(duplicate_leaves && other.begin()==other.end()) { // it's a leave
00782                                 append_child(position, (*other));
00783                                 }
00784                         else {
00785                                 if(other.begin()!=other.end())
00786                                         merge(fnd, other.begin(), duplicate_leaves);
00787                                 }
00788                         }
00789                 else {
00790                         insert(position.end(), oit);
00791                         }
00792                 ++oit;
00793                 }
00794         }
00795 
00796 template <class T, class tree_node_allocator>
00797 template <class StrictWeakOrdering> 
00798 bool tree<T, tree_node_allocator>::compare_nodes<StrictWeakOrdering>::operator()(const tree_node *a, 
00799                                                                                                                                                                                                                         const tree_node *b)
00800         {
00801         static StrictWeakOrdering comp;
00802 
00803         return comp(a->data, b->data);
00804         }
00805 
00806 template <class T, class tree_node_allocator>
00807 void tree<T, tree_node_allocator>::sort(sibling_iterator from, sibling_iterator to, bool deep)
00808         {
00809         std::less<T> comp;
00810         sort(from, to, comp, deep);
00811         }
00812 
00813 template <class T, class tree_node_allocator>
00814 template <class StrictWeakOrdering>
00815 void tree<T, tree_node_allocator>::sort(sibling_iterator from, sibling_iterator to, 
00816                                                                                                          StrictWeakOrdering comp, bool deep)
00817         {
00818         if(from==to) return;
00819         // make list of sorted nodes
00820         // CHECK: if multiset stores equivalent nodes in the order in which they
00821         // are inserted, then this routine should be called 'stable_sort'.
00822         std::multiset<tree_node *, compare_nodes<StrictWeakOrdering> > nodes;
00823         sibling_iterator it=from, it2=to;
00824         while(it != to) {
00825                 nodes.insert(it.node);
00826                 ++it;
00827                 }
00828         // reassemble
00829         --it2;
00830         tree_node *prev=from.node->prev_sibling;
00831         tree_node *next=it2.node->next_sibling;
00832         typename std::multiset<tree_node *, compare_nodes<StrictWeakOrdering> >::iterator nit=nodes.begin(), eit=nodes.end();
00833         if(prev==0) {
00834                 (*nit)->parent->first_child=(*nit);
00835                 }
00836         --eit;
00837         while(nit!=eit) {
00838                 (*nit)->prev_sibling=prev;
00839                 if(prev)
00840                         prev->next_sibling=(*nit);
00841                 prev=(*nit);
00842                 ++nit;
00843                 }
00844         if(prev)
00845                 prev->next_sibling=(*eit);
00846         (*eit)->next_sibling=next;
00847         if(next==0) {
00848                 (*eit)->parent->last_child=next;
00849                 }
00850 
00851         if(deep) {      // sort the children of each node too
00852                 sibling_iterator bcs(*nodes.begin());
00853                 sibling_iterator ecs(*eit);
00854                 ++ecs;
00855                 while(bcs!=ecs) {
00856                         sort(begin(bcs), end(bcs), comp, deep);
00857                         ++bcs;
00858                         }
00859                 }
00860         }
00861 
00862 template <class T, class tree_node_allocator>
00863 template <class BinaryPredicate>
00864 bool tree<T, tree_node_allocator>::equal(iterator one, iterator two, iterator three, BinaryPredicate fun) const
00865         {
00866         while(one!=two && three.is_valid()) {
00867                 if(one.number_of_children()!=three.number_of_children()) 
00868                         return false;
00869                 if(!fun(*one,*three))
00870                         return false;
00871                 ++one;
00872                 ++three;
00873                 }
00874         return true;
00875         }
00876 
00877 template <class T, class tree_node_allocator>
00878 tree<T, tree_node_allocator> tree<T, tree_node_allocator>::subtree(sibling_iterator from, sibling_iterator to) const
00879         {
00880         tree tmp;
00881         tmp.set_head(value_type());
00882         tmp.replace(tmp.begin(), tmp.end(), from, to);
00883         return tmp;
00884         }
00885 
00886 template <class T, class tree_node_allocator>
00887 void tree<T, tree_node_allocator>::subtree(tree& tmp, sibling_iterator from, sibling_iterator to) const
00888         {
00889         tmp.set_head(value_type());
00890         tmp.replace(tmp.begin(), tmp.end(), from, to);
00891         }
00892 
00893 template <class T, class tree_node_allocator>
00894 int tree<T, tree_node_allocator>::size() const
00895         {
00896         int i=0;
00897         iterator it=begin(), eit=end();
00898         while(it!=eit) {
00899                 ++i;
00900                 ++it;
00901                 }
00902         return i;
00903         }
00904 
00905 template <class T, class tree_node_allocator>
00906 int tree<T, tree_node_allocator>::depth(iterator it) const
00907         {
00908         tree_node* pos=it.node;
00909         assert(pos!=0);
00910         int ret=0;
00911         while(pos->parent!=0) {
00912                 pos=pos->parent;
00913                 ++ret;
00914                 }
00915         return ret;
00916         }
00917 
00918 template <class T, class tree_node_allocator>
00919 unsigned int tree<T, tree_node_allocator>::number_of_children(iterator it) const
00920         {
00921         tree_node *pos=it.node->first_child;
00922         if(pos==0) return 0;
00923         
00924         unsigned int ret=1;
00925         while(pos!=it.node->last_child) {
00926                 ++ret;
00927                 pos=pos->next_sibling;
00928                 }
00929         return ret;
00930         }
00931 
00932 template <class T, class tree_node_allocator>
00933 unsigned int tree<T, tree_node_allocator>::number_of_siblings(iterator it) const
00934         {
00935         tree_node *pos=it.node;
00936         unsigned int ret=1;
00937         while(pos->next_sibling && pos->next_sibling!=head) {
00938                 ++ret;
00939                 pos=pos->next_sibling;
00940                 }
00941         return ret;
00942         }
00943 
00944 template <class T, class tree_node_allocator>
00945 void tree<T, tree_node_allocator>::swap(sibling_iterator it)
00946         {
00947         tree_node *nxt=it.node->next_sibling;
00948         if(nxt) {
00949                 if(it.node->prev_sibling)
00950                         it.node->prev_sibling->next_sibling=nxt;
00951                 else
00952                         it.node->parent->first_child=nxt;
00953                 nxt->prev_sibling=it.node->prev_sibling;
00954                 tree_node *nxtnxt=nxt->next_sibling;
00955                 if(nxtnxt)
00956                         nxtnxt->prev_sibling=it.node;
00957                 else
00958                         it.node->parent->last_child=it.node;
00959                 nxt->next_sibling=it.node;
00960                 it.node->prev_sibling=nxt;
00961                 it.node->next_sibling=nxtnxt;
00962                 }
00963         }
00964 
00965 template <class T, class tree_node_allocator>
00966 bool tree<T, tree_node_allocator>::is_in_subtree(iterator it, iterator begin, iterator end) const
00967         {
00968         // FIXME: this should be optimised.
00969         iterator tmp=begin;
00970         while(tmp!=end) {
00971                 if(tmp==it) return true;
00972                 ++tmp;
00973                 }
00974         return false;
00975         }
00976 
00977 
00978 template <class T, class tree_node_allocator>
00979 T& tree<T, tree_node_allocator>::child(iterator it, unsigned int num) const
00980         {
00981         tree_node *tmp=it.node->first_child;
00982         while(num--) {
00983                 assert(tmp!=0);
00984                 tmp=tmp->next_sibling;
00985                 }
00986         return tmp->data;
00987         }
00988 
00989 // Iterator
00990 
00991 template <class T, class tree_node_allocator>
00992 tree<T, tree_node_allocator>::iterator::iterator() 
00993         : node(0), skip_current_children_(false)
00994         {
00995         }
00996 
00997 template <class T, class tree_node_allocator>
00998 tree<T, tree_node_allocator>::iterator::iterator(tree_node *tn)
00999         : node(tn), skip_current_children_(false)
01000         {
01001         }
01002 
01003 template <class T, class tree_node_allocator>
01004 tree<T, tree_node_allocator>::iterator::iterator(const sibling_iterator& other)
01005         : node(other.node), skip_current_children_(false)
01006         {
01007         if(node==0) {
01008                 if(other.range_last()!=0)
01009                         node=other.range_last();
01010                 else 
01011                         node=other.parent_;
01012                 skip_children();
01013                 increment_();
01014                 }
01015         }
01016 
01017 template <class T, class tree_node_allocator>
01018 T& tree<T, tree_node_allocator>::iterator::operator*(void) const
01019         {
01020         return node->data;
01021         }
01022 
01023 template <class T, class tree_node_allocator>
01024 T* tree<T, tree_node_allocator>::iterator::operator->(void) const
01025         {
01026         return &(node->data);
01027         }
01028 
01029 template <class T, class tree_node_allocator>
01030 typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::iterator::operator+(int num) const
01031         {
01032         iterator ret(*this);
01033         while(num>0) {
01034                 ++ret;
01035                 --num;
01036                 }
01037         return ret;
01038         }
01039 
01040 template <class T, class tree_node_allocator>
01041 typename tree<T, tree_node_allocator>::iterator& tree<T, tree_node_allocator>::iterator::operator++(void)
01042         {
01043         if(!increment_()) {
01044                 node=0;
01045                 }
01046         return *this;
01047         }
01048 
01049 template <class T, class tree_node_allocator>
01050 typename tree<T, tree_node_allocator>::iterator& tree<T, tree_node_allocator>::iterator::operator--(void)
01051         {
01052         if(!decrement_()) {
01053                 node=0;
01054                 }
01055         return *this;
01056         }
01057 
01058 template <class T, class tree_node_allocator>
01059 typename tree<T, tree_node_allocator>::iterator& tree<T, tree_node_allocator>::iterator::operator+=(unsigned int num)
01060         {
01061         while(num>0) {
01062                 ++(*this);
01063                 --num;
01064                 }
01065         return (*this);
01066         }
01067 
01068 template <class T, class tree_node_allocator>
01069 typename tree<T, tree_node_allocator>::iterator& tree<T, tree_node_allocator>::iterator::operator-=(unsigned int num)
01070         {
01071         while(num>0) {
01072                 --(*this);
01073                 --num;
01074                 }
01075         return (*this);
01076         }
01077 
01078 template <class T, class tree_node_allocator>
01079 bool tree<T, tree_node_allocator>::iterator::operator==(const iterator& other) const
01080         {
01081         if(other.node==node) return true;
01082         else return false;
01083         }
01084 
01085 template <class T, class tree_node_allocator>
01086 bool tree<T, tree_node_allocator>::iterator::operator!=(const iterator& other) const
01087         {
01088         if(other.node!=node) return true;
01089         else return false;
01090         }
01091 
01092 template <class T, class tree_node_allocator>
01093 typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::iterator::begin() const
01094         {
01095         sibling_iterator ret(node->first_child);
01096         ret.parent_=node;
01097         return ret;
01098         }
01099 
01100 template <class T, class tree_node_allocator>
01101 typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::iterator::end() const
01102         {
01103         sibling_iterator ret(0);
01104         ret.parent_=node;
01105         return ret;
01106         }
01107 
01108 template <class T, class tree_node_allocator>
01109 void tree<T, tree_node_allocator>::iterator::skip_children()
01110         {
01111         skip_current_children_=true;
01112         }
01113 
01114 template <class T, class tree_node_allocator>
01115 bool tree<T, tree_node_allocator>::iterator::is_valid() const
01116         {
01117         if(node==0) return false;
01118         else return true;
01119         }
01120 
01121 template <class T, class tree_node_allocator>
01122 bool tree<T, tree_node_allocator>::iterator::increment_()
01123         {
01124         assert(node!=0);
01125         if(!skip_current_children_ && node->first_child != 0) {
01126                 node=node->first_child;
01127                 return true;
01128                 }
01129         else {
01130                 skip_current_children_=false;
01131                 while(node->next_sibling==0) {
01132                         node=node->parent;
01133                         if(node==0)
01134                                 return false;
01135                         }
01136                 node=node->next_sibling;
01137                 return true;
01138                 }
01139         }
01140 
01141 template <class T, class tree_node_allocator>
01142 bool tree<T, tree_node_allocator>::iterator::decrement_()
01143         {
01144         assert(node!=0);
01145         if(node->parent==0) {
01146                 if(node->last_child==0)
01147                         node=node->prev_sibling;
01148                 while(node->last_child)
01149                         node=node->last_child;
01150                 if(!node) return false;
01151                 }
01152         else {
01153                 if(node->prev_sibling) {
01154                         if(node->prev_sibling->last_child) {
01155                                 node=node->prev_sibling->last_child;
01156                                 }
01157                         else {
01158                                 node=node->prev_sibling;
01159                                 }
01160                         }
01161                 else {
01162                         node=node->parent;
01163                         if(node==0)
01164                                 return false;
01165                         }
01166                 }
01167         return true;
01168         }
01169 
01170 template <class T, class tree_node_allocator>
01171 unsigned int tree<T, tree_node_allocator>::iterator::number_of_children() const
01172         {
01173         tree_node *pos=node->first_child;
01174         if(pos==0) return 0;
01175         
01176         unsigned int ret=1;
01177         while(pos!=node->last_child) {
01178                 ++ret;
01179                 pos=pos->next_sibling;
01180                 }
01181         return ret;
01182         }
01183 
01184 
01185 // Sibling iterator
01186 
01187 template <class T, class tree_node_allocator>
01188 tree<T, tree_node_allocator>::sibling_iterator::sibling_iterator() 
01189         : node(0), parent_(0)
01190         {
01191         }
01192 
01193 template <class T, class tree_node_allocator>
01194 tree<T, tree_node_allocator>::sibling_iterator::sibling_iterator(tree_node *tn)
01195         : node(tn)
01196         {
01197         set_parent_();
01198         }
01199 
01200 template <class T, class tree_node_allocator>
01201 tree<T, tree_node_allocator>::sibling_iterator::sibling_iterator(const iterator& other)
01202         : node(other.node)
01203         {
01204         set_parent_();
01205         }
01206 
01207 template <class T, class tree_node_allocator>
01208 tree<T, tree_node_allocator>::sibling_iterator::sibling_iterator(const sibling_iterator& other)
01209         : node(other.node), parent_(other.parent_)
01210         {
01211         }
01212 
01213 template <class T, class tree_node_allocator>
01214 void tree<T, tree_node_allocator>::sibling_iterator::set_parent_()
01215         {
01216         parent_=0;
01217         if(node==0) return;
01218         if(node->parent!=0)
01219                 parent_=node->parent;
01220         }
01221 
01222 template <class T, class tree_node_allocator>
01223 T& tree<T, tree_node_allocator>::sibling_iterator::operator*(void) const
01224         {
01225         return node->data;
01226         }
01227 
01228 template <class T, class tree_node_allocator>
01229 T* tree<T, tree_node_allocator>::sibling_iterator::operator->(void) const
01230         {
01231         return &(node->data);
01232         }
01233 
01234 template <class T, class tree_node_allocator>
01235 typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::sibling_iterator::operator+(int num) const
01236         {
01237         sibling_iterator ret(*this);
01238         while(num>0) {
01239                 ++ret;
01240                 --num;
01241                 }
01242         return ret;
01243         }
01244 
01245 template <class T, class tree_node_allocator>
01246 typename tree<T, tree_node_allocator>::sibling_iterator& tree<T, tree_node_allocator>::sibling_iterator::operator++(void)
01247         {
01248         if(node)
01249                 node=node->next_sibling;
01250         return *this;
01251         }
01252 
01253 template <class T, class tree_node_allocator>
01254 typename tree<T, tree_node_allocator>::sibling_iterator& tree<T, tree_node_allocator>::sibling_iterator::operator--(void)
01255         {
01256         if(node) node=node->prev_sibling;
01257         else {
01258                 assert(parent_);
01259                 node=parent_->last_child;
01260                 }
01261         return *this;
01262         }
01263 
01264 template <class T, class tree_node_allocator>
01265 typename tree<T, tree_node_allocator>::sibling_iterator& tree<T, tree_node_allocator>::sibling_iterator::operator+=(unsigned int num)
01266         {
01267         while(num>0) {
01268                 ++(*this);
01269                 --num;
01270                 }
01271         return (*this);
01272         }
01273 
01274 template <class T, class tree_node_allocator>
01275 typename tree<T, tree_node_allocator>::sibling_iterator& tree<T, tree_node_allocator>::sibling_iterator::operator-=(unsigned int num)
01276         {
01277         while(num>0) {
01278                 --(*this);
01279                 --num;
01280                 }
01281         return (*this);
01282         }
01283 
01284 template <class T, class tree_node_allocator>
01285 bool tree<T, tree_node_allocator>::sibling_iterator::operator==(const sibling_iterator& other) const
01286         {
01287         // We do not compare the parent node pointer, because end iterator may not always
01288         // have that information (for instance, when creating a sibling_iterator from a normal
01289         // iterator which is equal to the end() of the tree). This is not a problem, because 
01290         // the result of comparing two sibling_iterators which are not iterating over siblings of
01291         // the same node is undefined.
01292         if(other.node==node) return true;
01293         else return false;
01294         }
01295 
01296 template <class T, class tree_node_allocator>
01297 bool tree<T, tree_node_allocator>::sibling_iterator::operator!=(const sibling_iterator& other) const
01298         {
01299         if(other.node!=node) return true;
01300         else return false;
01301         }
01302 
01303 template <class T, class tree_node_allocator>
01304 bool tree<T, tree_node_allocator>::sibling_iterator::is_valid() const
01305         {
01306         if(node==0) return false;
01307         else return true;
01308         }
01309 
01310 template <class T, class tree_node_allocator>
01311 typename tree<T, tree_node_allocator>::tree_node *tree<T, tree_node_allocator>::sibling_iterator::range_first() const
01312         {
01313         tree_node *tmp=parent_->first_child;
01314         return tmp;
01315         }
01316 
01317 template <class T, class tree_node_allocator>
01318 typename tree<T, tree_node_allocator>::tree_node *tree<T, tree_node_allocator>::sibling_iterator::range_last() const
01319         {
01320         return parent_->last_child;
01321         }
01322 
01323 #endif
01324 
01325 // Local variables:
01326 // default-tab-width: 3
01327 // End:

Generated on Fri Sep 12 00:35:47 2003 for LibOFX by doxygen 1.3.3