FreeLing  3.1
tree.h
Go to the documentation of this file.
00001 
00002 //
00003 //    STL-like n-ary tree template 
00004 //
00005 //    Copyright (C) 2006   TALP Research Center
00006 //                         Universitat Politecnica de Catalunya
00007 //
00008 //    This program is free software; you can redistribute it 
00009 //    and/or modify it under the terms of the GNU General Public
00010 //    License as published by the Free Software Foundation; either
00011 //    version 3 of the License, or (at your option) any later version.
00012 //
00013 //    This library is distributed in the hope that it will be useful,
00014 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 //    General Public License for more details.
00017 //
00018 //    You should have received a copy of the GNU General Public
00019 //    License along with this library; if not, write to the Free Software
00020 //    Foundation, Inc., 51 Franklin St, 5th Floor, Boston, MA 02110-1301 USA
00021 //
00022 //    contact: Lluis Padro (padro@lsi.upc.es)
00023 //             TALP Research Center
00024 //             despatx Omega.S112 - Campus Nord UPC
00025 //             08034 Barcelona.  SPAIN
00026 //
00028 
00029 #ifndef _TREE_TEMPLATE
00030 #define _TREE_TEMPLATE
00031 
00032 namespace freeling {
00033 
00034   // predeclarations
00035   template <class T> class tree;
00036 
00037   template <class T> class generic_iterator;
00038   template <class T> class generic_const_iterator;
00039 
00040   template <class T> class preorder_iterator;
00041   template <class T> class const_preorder_iterator;
00042   template <class T> class sibling_iterator;
00043   template <class T> class const_sibling_iterator;
00044 
00046   template<class T, class N>
00047     class tree_iterator {
00048   protected:
00049     N *pnode;
00050   public: 
00051     tree_iterator();
00052     tree_iterator(tree<T> *);
00053     tree_iterator(const tree_iterator<T,N> &);
00054     ~tree_iterator();
00055 
00056     const tree<T>& operator*() const;
00057     const tree<T>* operator->() const;
00058     bool operator==(const tree_iterator<T,N> &) const;
00059     bool operator!=(const tree_iterator<T,N> &) const;
00060   };
00061 
00062   template<class T>
00063     class generic_iterator : public tree_iterator<T,tree<T> > {
00064     friend class generic_const_iterator<T>;
00065   public:
00066     generic_iterator();
00067     generic_iterator(tree<T> *);
00068     generic_iterator(const generic_iterator<T> &);
00069     tree<T>& operator*() const;
00070     tree<T>* operator->() const;
00071     ~generic_iterator();
00072   };
00073 
00074   template<class T>
00075     class generic_const_iterator : public tree_iterator<T,const tree<T> >  {
00076   public:
00077     generic_const_iterator();
00078     generic_const_iterator(const generic_iterator<T> &);
00079     generic_const_iterator(const generic_const_iterator<T> &);
00080     generic_const_iterator(tree<T> *);
00081     generic_const_iterator(const tree<T> *);
00082     ~generic_const_iterator();
00083   };
00084 
00085 
00087 
00088   template<class T>
00089     class sibling_iterator : public generic_iterator<T> {
00090   public:
00091     sibling_iterator();
00092     sibling_iterator(const sibling_iterator<T> &);
00093     sibling_iterator(tree<T> *);
00094     ~sibling_iterator();
00095 
00096     sibling_iterator& operator++();
00097     sibling_iterator& operator--();
00098     sibling_iterator operator++(int);
00099     sibling_iterator operator--(int);
00100   };
00101 
00102   template<class T>
00103     class const_sibling_iterator : public generic_const_iterator<T> {
00104   public:
00105     const_sibling_iterator();
00106     const_sibling_iterator(const const_sibling_iterator<T> &);
00107     const_sibling_iterator(const sibling_iterator<T> &);
00108     const_sibling_iterator(tree<T> *);
00109     ~const_sibling_iterator();
00110 
00111     const_sibling_iterator& operator++();
00112     const_sibling_iterator& operator--();
00113     const_sibling_iterator operator++(int);
00114     const_sibling_iterator operator--(int);
00115   };
00116 
00117 
00119   template<class T>
00120     class preorder_iterator : public generic_iterator<T> {
00121   public:
00122     preorder_iterator();
00123     preorder_iterator(const preorder_iterator<T> &);
00124     preorder_iterator(tree<T> *);
00125     preorder_iterator(const sibling_iterator<T> &);
00126     ~preorder_iterator();
00127 
00128     preorder_iterator& operator++();
00129     preorder_iterator& operator--();
00130     preorder_iterator operator++(int);
00131     preorder_iterator operator--(int);
00132   };
00133 
00134   template<class T>
00135     class const_preorder_iterator : public generic_const_iterator<T> {
00136   public:
00137     const_preorder_iterator();
00138     const_preorder_iterator(tree<T> *);
00139     const_preorder_iterator(const tree<T> *);
00140     const_preorder_iterator(const const_preorder_iterator<T> &);
00141     const_preorder_iterator(const preorder_iterator<T> &);
00142     const_preorder_iterator(const const_sibling_iterator<T> &);
00143     const_preorder_iterator(const sibling_iterator<T> &);
00144     ~const_preorder_iterator();
00145   
00146     const_preorder_iterator& operator++();
00147     const_preorder_iterator& operator--();
00148     const_preorder_iterator operator++(int);
00149     const_preorder_iterator operator--(int);
00150   };
00151 
00152   template <class T> 
00153     class tree { 
00154     friend class preorder_iterator<T>;
00155     friend class const_preorder_iterator<T>;
00156     friend class sibling_iterator<T>;
00157     friend class const_sibling_iterator<T>;
00158 
00159   private:
00160     bool isempty;
00161     tree *parent;        // parent node
00162     tree *first,*last;   // first/last child
00163     tree *prev,*next;    // prev/next sibling
00164     void clone(const tree<T>&);
00165 
00166   public:
00167     T info;
00168     typedef class generic_iterator<T> generic_iterator;
00169     typedef class generic_const_iterator<T> generic_const_iterator;
00170     typedef class preorder_iterator<T> preorder_iterator;
00171     typedef class const_preorder_iterator<T> const_preorder_iterator;
00172     typedef class sibling_iterator<T> sibling_iterator;
00173     typedef class const_sibling_iterator<T> const_sibling_iterator;
00174     typedef preorder_iterator iterator;
00175     typedef const_preorder_iterator const_iterator;
00176 
00177     tree();
00178     tree(const T&);
00179     tree(const tree<T>&);
00180     tree(const typename tree<T>::preorder_iterator&);
00181     ~tree();
00182     tree<T>& operator=(const tree<T>&);
00183 
00184     unsigned int num_children() const;
00185     sibling_iterator nth_child(unsigned int) const;
00186     iterator get_parent() const;
00187     tree<T> & nth_child_ref(unsigned int) const;
00188     T& get_info();
00189     void append_child(const tree<T> &);
00190     void hang_child(tree<T> &, bool=true);
00191     void clear();
00192     bool empty() const;
00193 
00194     sibling_iterator sibling_begin();
00195     const_sibling_iterator sibling_begin() const;
00196     sibling_iterator sibling_end();
00197     const_sibling_iterator sibling_end() const;
00198     sibling_iterator sibling_rbegin();
00199     const_sibling_iterator sibling_rbegin() const;
00200     sibling_iterator sibling_rend();
00201     const_sibling_iterator sibling_rend() const;
00202 
00203     preorder_iterator begin();
00204     const_preorder_iterator begin() const;
00205     preorder_iterator end();
00206     const_preorder_iterator end() const;
00207   };
00208 
00209 
00211 
00213 
00214   template <class T>
00215     tree<T>::tree() {
00216     isempty = true;
00217     parent=NULL;
00218     first=NULL; last=NULL;
00219     prev=NULL; next=NULL;
00220   }
00221 
00222 
00224 
00225   template <class T>
00226     tree<T>::tree(const T &x) : info(x) {
00227     isempty = false;
00228     parent=NULL;
00229     first=NULL; last=NULL;
00230     prev=NULL; next=NULL;
00231   }
00232 
00234 
00235   template <class T>
00236     tree<T>::tree(const typename tree<T>::preorder_iterator &p) {
00237     clone(*p);
00238   }
00239 
00241 
00242   template <class T>
00243     tree<T>::tree(const tree<T>& t) {
00244     clone(t);
00245   }
00246 
00247 
00249 
00250   template <class T>
00251     tree<T>& tree<T>::operator=(const tree<T>& t) {
00252     if (this != &t) {
00253       clear();
00254       clone(t);
00255     }
00256     return (*this);
00257   }
00258 
00260 
00261   template <class T>
00262     tree<T>::~tree() {
00263     tree *p=this->first;
00264     while (p!=NULL) {
00265       tree *q=p->next;
00266       delete p;
00267       p=q;
00268     }
00269   }
00270 
00271   template <class T>
00272     void tree<T>::clear() {
00273 
00274     // delete children
00275     tree *p=this->first;
00276     while (p!=NULL) {
00277       tree *q=p->next;
00278       delete p;
00279       p=q;
00280     }
00281 
00282     // reset root node
00283     isempty = true;
00284     parent=NULL;
00285     first=NULL; last=NULL;
00286     prev=NULL; next=NULL;
00287 
00288   }
00289 
00291 
00292   template <class T>
00293     unsigned int tree<T>::num_children() const {
00294     tree *s;
00295     unsigned int n=0;
00296     for (s=this->first; s!=NULL; s=s->next) n++;
00297     return n;
00298   }
00299 
00301 
00302   template <class T>
00303     typename tree<T>::iterator tree<T>::get_parent() const { 
00304     iterator i = this->parent;    
00305     return i;
00306   }
00307 
00309 
00310   template <class T>
00311     typename tree<T>::sibling_iterator tree<T>::nth_child(unsigned int n) const { 
00312     sibling_iterator i = this->first;    
00313     while (n>0 && i!=NULL) {
00314       i = i->next;
00315       n--;
00316     }
00317     return i;
00318   }
00319 
00320 
00322 
00323   template <class T>
00324     tree<T> & tree<T>::nth_child_ref(unsigned int n) const { 
00325     sibling_iterator i = this->first;
00326     while (n>0) {
00327       i = i->next;
00328       n--;
00329     }
00330     return (*i);
00331   }
00332 
00334 
00335   template <class T>
00336     T& tree<T>::get_info() {
00337     return info;
00338   }
00339 
00340 
00342 
00343   template <class T>
00344     bool tree<T>::empty() const {
00345     return isempty;
00346   }
00347 
00349 
00350   template <class T>
00351     typename tree<T>::sibling_iterator tree<T>::sibling_begin() {
00352     return freeling::sibling_iterator<T>(this->first);
00353   }
00354 
00355   template <class T>
00356     typename tree<T>::const_sibling_iterator tree<T>::sibling_begin() const {
00357     return freeling::const_sibling_iterator<T>(this->first);
00358   }
00359 
00360   template <class T>
00361     typename tree<T>::sibling_iterator tree<T>::sibling_end() {
00362     return freeling::sibling_iterator<T>(NULL);
00363   }
00364 
00365   template <class T>
00366     typename tree<T>::const_sibling_iterator tree<T>::sibling_end() const {
00367     return freeling::const_sibling_iterator<T>(NULL);
00368   }
00369 
00370 
00372 
00373   template <class T>
00374     typename tree<T>::preorder_iterator tree<T>::begin() {
00375     if (isempty) return freeling::preorder_iterator<T>(NULL);
00376     else return freeling::preorder_iterator<T>(this);
00377   }
00378 
00379   template <class T>
00380     typename tree<T>::const_preorder_iterator tree<T>::begin() const {
00381     if (isempty) return freeling::const_preorder_iterator<T>((const tree<T>*)NULL);
00382     else return freeling::const_preorder_iterator<T>(this);
00383   }
00384 
00385   template <class T>
00386     typename tree<T>::preorder_iterator tree<T>::end() {
00387     return freeling::preorder_iterator<T>((tree<T>*)NULL);
00388   }
00389 
00390   template <class T>
00391     typename tree<T>::const_preorder_iterator tree<T>::end() const {
00392     return freeling::const_preorder_iterator<T>((const tree<T>*)NULL);
00393   }
00394 
00395   template <class T>
00396     typename tree<T>::sibling_iterator tree<T>::sibling_rbegin() {
00397     return freeling::sibling_iterator<T>(this->last);
00398   }
00399 
00400   template <class T>
00401     typename tree<T>::const_sibling_iterator tree<T>::sibling_rbegin() const {
00402     return freeling::const_sibling_iterator<T>(this->last);
00403   }
00404 
00405   template <class T>
00406     typename tree<T>::sibling_iterator tree<T>::sibling_rend() {
00407     return freeling::sibling_iterator<T>(NULL);
00408   }
00409 
00410   template <class T>
00411     typename tree<T>::const_sibling_iterator tree<T>::sibling_rend() const {
00412     return freeling::const_sibling_iterator<T>(NULL);
00413   }
00414 
00415 
00417 
00418   template <class T>
00419     void tree<T>::append_child(const tree<T>& child) {
00420 
00421     // make a copy
00422     tree<T> *x = new tree<T>;
00423     x->clone(child);
00424 
00425     x->next = NULL;  x->prev = NULL;
00426     x->parent = this;
00427 
00428     if (this->first != NULL) {  // there are already children, join them
00429       x->prev = this->last;
00430       this->last->next = x;
00431       this->last = x;
00432     }
00433     else {
00434       // no children, new is the only one
00435       this->first = x; this->last = x;
00436     }
00437   }
00438 
00440 
00441   template <class T>
00442     void tree<T>::hang_child(tree<T>& child, bool last) {
00443 
00444     // remove child from its current location:
00445     // 1- remove it from siblings chain
00446     if (child.prev) child.prev->next=child.next;
00447     if (child.next) child.next->prev=child.prev;  
00448     // 2- adujst parent pointers if first or last child
00449     if (child.parent) {
00450       if (!child.prev) child.parent->first=child.next;
00451       if (!child.next) child.parent->last=child.prev;
00452     }
00453 
00454     // hang child on new location
00455     child.prev=NULL;
00456     child.next=NULL;
00457     child.parent = this;
00458 
00459     if (this->first == NULL) { 
00460       // there are no children, new is the only one
00461       this->first = &child;
00462       this->last = &child;
00463     }
00464     else {
00465       // already children, join them
00466       if (last) {
00467         // append new node as last child
00468         child.prev = this->last;
00469         this->last->next = &child;
00470         this->last = &child;
00471       }
00472       else {
00473         // append new node as first child
00474         child.next = this->first;
00475         this->first->prev = &child;
00476         this->first = &child;      
00477       }
00478     }
00479   }
00480 
00482 
00483   template <class T>
00484     void tree<T>::clone(const tree<T>& t) {
00485 
00486     this->isempty = t.isempty;
00487     this->info = t.info;
00488     this->parent = NULL;
00489     this->first = NULL;
00490     this->last = NULL;
00491     this->prev=NULL;
00492     this->next=NULL;
00493 
00494     for (tree* p=t.first; p!=NULL; p=p->next) {
00495 
00496       tree<T>* c = new tree<T>;
00497       c->clone(*p);
00498       c->next = NULL;  
00499       c->prev = NULL;
00500       c->parent = this;
00501 
00502       if (this->first != NULL) {
00503         c->prev = this->last;
00504         this->last->next = c;
00505         this->last = c;
00506       }
00507       else {
00508         this->first = c; 
00509         this->last = c;
00510       }
00511     }
00512   }
00513 
00514 
00516   template <class T, class N>
00517     tree_iterator<T,N>::tree_iterator() {pnode = NULL;}
00518 
00519   template <class T, class N>
00520     tree_iterator<T,N>::tree_iterator(tree<T> *t) {pnode = t;}
00521 
00522   template <class T, class N>
00523     tree_iterator<T,N>::tree_iterator(const tree_iterator<T,N> &o) : pnode(o.pnode) {}
00524 
00525   template <class T, class N>
00526     tree_iterator<T,N>::~tree_iterator() {}
00527 
00528   template <class T, class N>
00529     const tree<T>& tree_iterator<T,N>::operator*() const {return (*pnode);}
00530 
00531   template <class T, class N>
00532     const tree<T>* tree_iterator<T,N>::operator->() const {return pnode;}
00533 
00534   template <class T, class N>
00535     bool tree_iterator<T,N>::operator==(const tree_iterator<T,N> &t) const {
00536     return (t.pnode==pnode); 
00537   }
00538 
00539   template <class T, class N>
00540     bool tree_iterator<T,N>::operator!=(const tree_iterator<T,N> &t) const {
00541     return (t.pnode!=pnode); 
00542   }
00543 
00545 
00546   template <class T>
00547     generic_iterator<T>::generic_iterator() : tree_iterator<T,tree<T> >() {}
00548 
00549   template <class T>
00550     generic_iterator<T>::generic_iterator(const generic_iterator<T> & o) : tree_iterator<T,tree<T> >(o.pnode) {}
00551 
00552   template <class T>
00553     generic_iterator<T>::generic_iterator(tree<T> *t) : tree_iterator<T,tree<T> >() {this->pnode=t;}
00554 
00555   template <class T>
00556     generic_iterator<T>::~generic_iterator() {}
00557 
00558   template <class T>
00559     tree<T>& generic_iterator<T>::operator*() const {return (*this->pnode);}
00560 
00561   template <class T>
00562     tree<T>* generic_iterator<T>::operator->() const {return this->pnode;}
00563 
00564 
00566 
00567   template <class T>
00568     generic_const_iterator<T>::generic_const_iterator() : tree_iterator<T,const tree<T> >() {}
00569 
00570   template <class T>
00571     generic_const_iterator<T>::generic_const_iterator(const generic_iterator<T> & o) : tree_iterator<T,const tree<T> >(o.pnode) {}
00572 
00573   template <class T>
00574     generic_const_iterator<T>::generic_const_iterator(const generic_const_iterator<T> & o) : tree_iterator<T,const tree<T> >() {this->pnode=o.pnode;}
00575 
00576   template <class T>
00577     generic_const_iterator<T>::generic_const_iterator(tree<T> *t) : tree_iterator<T,const tree<T> >(t) {}
00578 
00579   template <class T>
00580     generic_const_iterator<T>::generic_const_iterator(const tree<T> *t) : tree_iterator<T,const tree<T> >() {this->pnode=t;}
00581 
00582   template <class T>
00583     generic_const_iterator<T>::~generic_const_iterator() {}
00584 
00585 
00586 
00587 
00588 
00590 
00591   template <class T>
00592     preorder_iterator<T>::preorder_iterator() : generic_iterator<T>() {}
00593 
00594   template <class T>
00595     preorder_iterator<T>::preorder_iterator(const preorder_iterator<T> & o) : generic_iterator<T>(o) {}
00596 
00597   template <class T>
00598     preorder_iterator<T>::preorder_iterator(const sibling_iterator<T> & o) : generic_iterator<T>(o) {}
00599 
00600   template <class T>
00601     preorder_iterator<T>::preorder_iterator(tree<T> *t) : generic_iterator<T>(t) {}
00602 
00603   template <class T>
00604     preorder_iterator<T>::~preorder_iterator() {}
00605 
00606 
00607 
00608   template <class T>
00609     preorder_iterator<T>& preorder_iterator<T>::operator++() {
00610     if (this->pnode->first != NULL) 
00611       this->pnode=this->pnode->first;
00612     else {
00613       while (this->pnode!=NULL && this->pnode->next==NULL) 
00614         this->pnode=this->pnode->parent;
00615       if (this->pnode!=NULL) this->pnode=this->pnode->next;
00616     }
00617     return *this;
00618   }
00619 
00620   template <class T>
00621     preorder_iterator<T>& preorder_iterator<T>::operator--() {
00622     if (this->pnode->prev!=NULL) {
00623       this->pnode=this->pnode->prev;
00624       while (this->pnode->last != NULL)
00625         this->pnode=this->pnode->last;
00626     }
00627     else
00628       this->pnode = this->pnode->parent;
00629 
00630     return *this;
00631   }
00632 
00633   template <class T>
00634     preorder_iterator<T> preorder_iterator<T>::operator++(int) {
00635     preorder_iterator b=(*this);
00636     ++(*this);
00637     return b;
00638   }
00639 
00640   template <class T>
00641     preorder_iterator<T> preorder_iterator<T>::operator--(int) {
00642     preorder_iterator b=(*this);
00643     --(*this);
00644     return b;
00645   }
00646 
00647 
00649 
00650   template <class T>
00651     const_preorder_iterator<T>::const_preorder_iterator() : generic_const_iterator<T>() {}
00652 
00653   template <class T>
00654     const_preorder_iterator<T>::const_preorder_iterator(const preorder_iterator<T> & o) : generic_const_iterator<T>(o) {}
00655 
00656   template <class T>
00657     const_preorder_iterator<T>::const_preorder_iterator(const sibling_iterator<T> & o) : generic_const_iterator<T>(o) {}
00658 
00659   template <class T>
00660     const_preorder_iterator<T>::const_preorder_iterator(const const_preorder_iterator<T> & o) : generic_const_iterator<T>(o) {}
00661 
00662   template <class T>
00663     const_preorder_iterator<T>::const_preorder_iterator(const const_sibling_iterator<T> & o) : generic_const_iterator<T>(o) {}
00664 
00665   template <class T>
00666     const_preorder_iterator<T>::~const_preorder_iterator() {}
00667 
00668   template <class T>
00669     const_preorder_iterator<T>::const_preorder_iterator(tree<T> *t) : generic_const_iterator<T>(t) {}
00670 
00671   template <class T>
00672     const_preorder_iterator<T>::const_preorder_iterator(const tree<T> *t) : generic_const_iterator<T>(t) {}
00673 
00674   template <class T>
00675     const_preorder_iterator<T>& const_preorder_iterator<T>::operator++() {
00676     if (this->pnode->first != NULL) 
00677       this->pnode=this->pnode->first;
00678     else {
00679       while (this->pnode!=NULL && this->pnode->next==NULL) 
00680         this->pnode=this->pnode->parent;
00681       if (this->pnode!=NULL) this->pnode=this->pnode->next;
00682     }
00683     return *this;
00684   }
00685 
00686   template <class T>
00687     const_preorder_iterator<T>& const_preorder_iterator<T>::operator--() {
00688     if (this->pnode->prev!=NULL) {
00689       this->pnode=this->pnode->prev;
00690       while (this->pnode->last != NULL)
00691         this->pnode=this->pnode->last;
00692     }
00693     else
00694       this->pnode = this->pnode->parent;
00695 
00696     return *this;
00697   }
00698 
00699   template <class T>
00700     const_preorder_iterator<T> const_preorder_iterator<T>::operator++(int) {
00701     const_preorder_iterator b=(*this);
00702     ++(*this);
00703     return b;
00704   }
00705 
00706   template <class T>
00707     const_preorder_iterator<T> const_preorder_iterator<T>::operator--(int) {
00708     const_preorder_iterator b=(*this);
00709     --(*this);
00710     return b;
00711   }
00712 
00713 
00714   /*
00715     template <class T>
00716     const_preorder_iterator<T>& const_preorder_iterator<T>::operator+=(unsigned int n) {
00717     for (; n>0; n--) ++(*this);
00718     return *this;
00719     }
00720 
00721     template <class T>
00722     const_preorder_iterator<T>& const_preorder_iterator<T>::operator-=(unsigned int n) {
00723     for (; n>0; n--) --(*this);
00724     return *this;
00725     }
00726   */
00727 
00729 
00730   template <class T>
00731     sibling_iterator<T>::sibling_iterator() : generic_iterator<T>() {}
00732 
00733   template <class T>
00734     sibling_iterator<T>::sibling_iterator(const sibling_iterator<T> & o) : generic_iterator<T>(o) {}
00735 
00736   template <class T>
00737     sibling_iterator<T>::sibling_iterator(tree<T> *t) : generic_iterator<T>(t) {}
00738 
00739   template <class T>
00740     sibling_iterator<T>::~sibling_iterator() {}
00741 
00742   template <class T>
00743     sibling_iterator<T>& sibling_iterator<T>::operator++() {
00744     this->pnode = this->pnode->next; 
00745     return *this;
00746   }
00747 
00748   template <class T>
00749     sibling_iterator<T>& sibling_iterator<T>::operator--() {
00750     this->pnode = this->pnode->prev; 
00751     return *this;
00752   }
00753 
00754 
00755   template <class T>
00756     sibling_iterator<T> sibling_iterator<T>::operator++(int) {
00757     sibling_iterator b=(*this);
00758     ++(*this);
00759     return b;
00760   }
00761 
00762   template <class T>
00763     sibling_iterator<T> sibling_iterator<T>::operator--(int) {
00764     sibling_iterator b=(*this);
00765     --(*this);
00766     return b;
00767   }
00768 
00769   /*template <class T>
00770     sibling_iterator<T>& sibling_iterator<T>::operator+=(unsigned int n) {
00771     for (; n>0; n--) ++(*this);
00772     return *this;
00773     }
00774 
00775     template <class T>
00776     sibling_iterator<T>& sibling_iterator<T>::operator-=(unsigned int n) {
00777     for (; n>0; n--) --(*this);
00778     return *this;
00779     }
00780   */
00781 
00783 
00784   template <class T>
00785     const_sibling_iterator<T>::const_sibling_iterator() : generic_const_iterator<T>() {}
00786 
00787   template <class T>
00788     const_sibling_iterator<T>::const_sibling_iterator(const sibling_iterator<T> & o) : generic_const_iterator<T>(o) {}
00789 
00790   template <class T>
00791     const_sibling_iterator<T>::const_sibling_iterator(const const_sibling_iterator<T> & o) : generic_const_iterator<T>(o) {}
00792 
00793   template <class T>
00794     const_sibling_iterator<T>::const_sibling_iterator(tree<T> *t) : generic_const_iterator<T>(t) {}
00795 
00796   template <class T>
00797     const_sibling_iterator<T>::~const_sibling_iterator() {}
00798 
00799 
00800   template <class T>
00801     const_sibling_iterator<T>& const_sibling_iterator<T>::operator++() {
00802     this->pnode = this->pnode->next; 
00803     return *this;
00804   }
00805 
00806   template <class T>
00807     const_sibling_iterator<T>& const_sibling_iterator<T>::operator--() {
00808     this->pnode = this->pnode->prev; 
00809     return *this;
00810   }
00811 
00812 
00813   template <class T>
00814     const_sibling_iterator<T> const_sibling_iterator<T>::operator++(int) {
00815     const_sibling_iterator b=(*this);
00816     ++(*this);
00817     return b;
00818   }
00819 
00820   template <class T>
00821     const_sibling_iterator<T> const_sibling_iterator<T>::operator--(int) {
00822     const_sibling_iterator b=(*this);
00823     --(*this);
00824     return b;
00825   }
00826 
00827 
00828 } // namespace
00829 
00830 #endif
00831