proj home

Files   Classes   Functions   Hierarchy  

treeindexediter.h

Go to the documentation of this file.
00001 #ifndef TREEINDEXEDD2ITER_H
00002 #define TREEINDEXEDD2ITER_H
00003 
00004 #include <treeindexedD2.h>
00005 
00023 template< typename T >
00024 class treeindexedD2iter
00025 {
00026 public:
00027 
00030   vector< treeindexedD2node<T> * > path;
00031 
00033   treeindexedD2<T> & tree;
00034 
00036   treeindexedD2iter(treeindexedD2<T> & tree_, boolc setreset=true)
00037     : tree(tree_) { if (setreset) reset(); }
00038 
00040   void reset();
00041 
00044   void movedown();
00045 
00047   void operator ++ ();
00048 
00050   boolc operator !() const
00051     { return !path.empty(); }
00052 
00054   treeindexedD2node<T> * operator () () const
00055     { assert(path.size()>0); return path[path.size()-1]; }
00056 };
00057 
00058 
00069 template< typename T >
00070 class treeindexedD2iterleaf : public treeindexedD2iter<T>
00071 {
00072 public:
00073 
00075   treeindexedD2iterleaf
00076   (
00077     treeindexedD2<T> & tree_, 
00078     boolc setreset=true
00079   )
00080     : treeindexedD2iter<T>(tree_,setreset) {}
00081 
00083   void operator ++ ();
00084 };
00085 
00089 template< typename T >
00090 class treeindexedD2iterinternal : public treeindexedD2iter<T>
00091 {
00092 public:
00093 
00095   treeindexedD2iterinternal
00096   (
00097     treeindexedD2<T> & tree_, 
00098     boolc setreset=true
00099   );
00100 
00102   void operator ++ ();
00103 
00105   void reset();
00106 };
00107 
00108 
00109 //---------------------------------------------------------
00110 //  Implementation
00111 
00112 template <typename T>
00113 void treeindexedD2iterinternal<T>::reset()
00114 {
00115   treeindexedD2iter<T>::reset();
00116 
00117   // Warning, deliberate duplicate code - same as in constructor treeindexedD2iterinternal(...).
00118 
00119   if (! treeindexedD2iter<T>::operator !())
00120     return;
00121 
00122   if (treeindexedD2iter<T>::operator()()->isleaf())
00123     treeindexedD2iterinternal<T>::operator++();
00124 }
00125 
00126 template <typename T>
00127 treeindexedD2iterinternal<T>::treeindexedD2iterinternal
00128 (
00129   treeindexedD2<T> & tree_, 
00130   boolc setreset
00131 )
00132   : treeindexedD2iter<T>(tree_,setreset) 
00133 {
00134   if (setreset==false)
00135     return;
00136 
00137   // Warning, deliberate duplicate code - same as in reset().
00138 
00139   if (! treeindexedD2iter<T>::operator !())
00140     return;
00141 
00142   if (treeindexedD2iter<T>::operator()()->isleaf())
00143     treeindexedD2iterinternal<T>::operator++();
00144 }
00145 
00146 template <typename T>
00147 void treeindexedD2iterinternal<T>::operator ++ ()
00148 {
00149   treeindexedD2iter<T>::operator ++ ();
00150 
00151   while (treeindexedD2iter<T>::operator ! ()) 
00152   {
00153     if (! treeindexedD2iter<T>::operator ()()->isleaf())
00154       return;
00155 
00156     treeindexedD2iter<T>::operator ++ ();
00157   }
00158 }
00159 
00160 template <typename T>
00161 void treeindexedD2iterleaf<T>::operator ++ ()
00162 {
00163   treeindexedD2iter<T>::operator ++ ();
00164 
00165   while (treeindexedD2iter<T>::operator ! ()) 
00166   {
00167     if (treeindexedD2iter<T>::operator ()()->isleaf())
00168       return;
00169 
00170     treeindexedD2iter<T>::operator ++ ();
00171   }
00172 }
00173 
00174 
00175 template <typename T>
00176 void treeindexedD2iter<T>::operator ++ ()
00177 {
00178   uint sz = path.size();
00179   if (sz<=1)
00180   {
00181     if (sz==0)
00182       return;
00183 
00184     path.pop_back();
00185     return;
00186   }
00187 
00188   --sz;
00189   treeindexedD2node<T> * current = path[sz];
00190   path.pop_back();
00191 
00192   treeindexedD2node<T> * parent = path[sz-1];
00193 
00194   if (current->isleaf())
00195   {
00196     if (parent->left==current)
00197     {
00198       if (parent->right!=0)
00199       {
00200         path.push_back(parent->right);
00201         movedown();
00202         return;
00203       }
00204 
00205       return;
00206     }
00207 
00208     if (parent->right==current)
00209       return;
00210 
00211     assert(false);
00212   }
00213 
00214   // The node is not a leaf therefore it is internal.
00215   // Therefore moving up.
00216 
00217   // Is it a left branch?
00218   if (parent->left==current)
00219   {
00220     if (parent->right!=0)
00221     {
00222       path.push_back(parent->right);
00223       movedown();
00224       return;
00225     }
00226 
00227     return;
00228   }
00229 
00230   if (parent->right==current)
00231     return;
00232 
00233   assert(false);
00234 }
00235 
00236 template <typename T>
00237 void treeindexedD2iter<T>::reset()
00238 {
00239   path.clear();
00240   treeindexedD2node<T> * current = tree.root;
00241   if (current==0)
00242     return;
00243 
00244   path.push_back(current);
00245   movedown();
00246 }
00247 
00248 template <typename T>
00249 void treeindexedD2iter<T>::movedown()
00250 {
00251   assert(path.size()>0);
00252 
00253   treeindexedD2node<T> * current = path[path.size()-1];
00254   assert(current!=0);
00255 
00256   for ( ; current!=0; )
00257   {
00258     if (current->left!=0)
00259     {
00260       current = current->left;
00261       path.push_back(current);
00262       continue;
00263     }
00264 
00265     if (current->right!=0)
00266     {
00267       current = current->right;
00268       path.push_back(current);
00269       continue;
00270     }
00271 
00272     current=0;
00273   }
00274 
00275 }
00276   
00277 
00278 
00279 #endif
00280 
00281 

Generated on Fri Mar 4 00:49:26 2011 for Chelton Evans Source by  doxygen 1.5.8