Gamma  0.9.5
Generic Synthesis Library
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
/Users/ljp/code/gamma/trunk/Gamma/Node.h
00001 #ifndef GAMMA_NODE_H_INC
00002 #define GAMMA_NODE_H_INC
00003 
00004 /*  Gamma - Generic processing library
00005     See COPYRIGHT file for authors and license information */
00006 
00007 #include <stdio.h>
00008 
00009 #define TEM template <class T>
00010 
00011 namespace gam{
00012 
00014 template <class T>
00015 class Node2{
00016 public:
00017     Node2();
00018     Node2(bool zeroLinks);
00019     //virtual ~Node2();
00020     ~Node2();
00021     
00022     T * nodeL;                  
00023     T * nodeR;                  
00024     
00025     void nodeInsertL(T& node);  
00026     void nodeInsertR(T& node);  
00027     void nodeRemove();          
00028     
00029     const Node2<T>& leftmost() const {
00030         Node2<T> * t = nodeL;
00031         Node2<T> * n = nodeL;
00032         while(t){ n = t; t = t->nodeL; }
00033         return n ? *n : *this;
00034     }
00035     
00036     void print(const char * append = "\n", FILE * fp = stdout) const;
00037     void printAll(const char * append = "\n", FILE * fp = stdout) const;
00038 };
00039 
00040 
00042 template <class T>
00043 class Node3{
00044 public:
00045 
00046     T * parent;     
00047     T * child;      
00048     T * sibling;    
00049 
00050     Node3()
00051     :   parent(0), child(0), sibling(0)
00052     {}
00053     
00054 //  const T * parent() const { return mParent; }
00055 //  const T * child() const { return mChild; }
00056 //  const T * sibling() const { return mSibling; }
00057 //
00058 //  T * parent(){ return mParent; }
00059 //  T * child(){ return mChild; }
00060 //  T * sibling(){ return mSibling; }
00061 
00063     void addFirstChild(T * newChild){
00064         newChild->removeFromParent();
00065         newChild->parent = self();
00066         newChild->sibling = child;
00067         child = newChild;
00068     }
00069 
00071     void addLastChild(T * newChild){
00072         newChild->removeFromParent();
00073         newChild->parent = self();
00074         if(!child){ // No children, so make first child
00075             child = newChild;
00076         }
00077         else{       // Have children, so add to end of children
00078             lastChild()->sibling = newChild;
00079         }
00080     }
00081     
00083     void removeFromParent(){
00084 
00085         if(parent && parent->child){
00086 
00087             // re-patch parent's child?
00088             if(parent->child == self()){
00089                 // I'm my parent's first child 
00090                 // - remove my reference, but keep the sibling list healthy
00091                 parent->child = sibling;
00092             }
00093             
00094             // re-patch the sibling chain?
00095             else{
00096                 // I must be one of parent->child's siblings
00097                 T * temp = parent->child;
00098                 while(temp->sibling){
00099                     if(temp->sibling == self()) {
00100                         // I'm temp's sibling
00101                         // - remove my reference, keep the sibling list healthy
00102                         temp->sibling = this->sibling; 
00103                         break; 
00104                     }
00105                     temp = temp->sibling;
00106                 }
00107             }
00108             
00109             parent=0; sibling=0; // no more parent or sibling, but child is still valid
00110         }
00111     }
00112 
00113     T * lastChild(){
00114         T * n = child;
00115         while(n->sibling) n = n->sibling;
00116         return n;
00117     }
00118 
00120     
00123     T * next(const T * const terminal){     
00124         T * n = self();
00125         
00126         if(n->child){
00127             n = n->child;
00128             return (n != terminal) ? n : 0;
00129         }
00130         else{
00131             return nextBreadth(terminal);
00132         }
00133     }
00134 
00135     const T * next(const T * const terminal) const {        
00136         return const_cast<const T*>(next(terminal));
00137     }
00138     
00140     T * nextBreadth(const T * const terminal){
00141         T * n = self();
00142         if(n->sibling){
00143             n = n->sibling;
00144         }
00145         else{
00146             while(n != terminal && n->sibling == 0){
00147                 n = n->parent;
00148             }
00149             if(n != terminal && n->sibling){
00150                 n = n->sibling;
00151             }
00152         }
00153         return (n != terminal) ? n : 0;
00154     }
00155 
00156 private:
00157     T * self(){ return static_cast<T*>(this); }
00158     const T * self() const { return static_cast<T*>(this); }
00159 };
00160 
00161 
00163 template <class T>
00164 class Node4{
00165 public:
00166 
00167     Node4();
00168     //virtual ~Node4();
00169     ~Node4();
00170 
00171     T * parent;     
00172     T * child;      
00173     T * right;      
00174     T * left;       
00175 
00176     void add(T * node);         
00177     
00179     
00182     void remove();              
00183 
00184     void setAsFirstChild();     
00185     void setAsLastChild();      
00186 
00188     
00191     T * next(const T * terminal) const;
00192 
00193     void print(const char * append="");             
00194     void printDescendents(const char * append="");  
00195 };
00196 
00197 
00198 // Implementation_______________________________________________________________
00199 
00200 // Node2
00201 
00202 TEM Node2<T>::Node2()
00203 :   nodeL(0), nodeR(0)
00204 {
00205 }
00206 
00207 TEM Node2<T>::Node2(bool zeroLinks){
00208     if(zeroLinks){
00209         nodeL = 0;
00210         nodeR = 0;
00211     }
00212 }
00213 
00214 TEM Node2<T>::~Node2(){
00215     //printf("~Node2\n");
00216     nodeRemove();
00217 }
00218 
00219 TEM void Node2<T>::nodeInsertL(T & node){
00220     nodeL = node.nodeL;
00221     nodeR = &node;
00222     if(nodeL) nodeL->nodeR = (T *)this;
00223     node.nodeL = (T *)this;
00224 }
00225 
00226 TEM void Node2<T>::nodeInsertR(T & node){
00227     nodeR = node.nodeR;
00228     nodeL = &node;
00229     if(nodeR) nodeR->nodeL = (T *)this;
00230     node.nodeR = (T *)this;
00231 }
00232 
00233 TEM void Node2<T>::nodeRemove(){
00234     // connect neighbors
00235     if(nodeL){ nodeL->nodeR = nodeR; }
00236     if(nodeR){ nodeR->nodeL = nodeL; }
00237     nodeL = 0;
00238     nodeR = 0;
00239 }
00240 
00241 
00242 
00243 TEM void Node2<T>::print(const char * append, FILE * fp) const {
00244     fprintf(fp, "%p %p %p%s", nodeL, this, nodeR, append);
00245 }
00246 
00247 TEM void Node2<T>::printAll(const char * append, FILE * fp) const {
00248 
00249     Node2<T> const * n = &leftmost();
00250     
00251     while(n){
00252         fprintf(fp, n == this ? "(%p) " : " %p  ", n);
00253         n = n->nodeR;
00254     }
00255     fprintf(fp, append);
00256 }
00257 
00258 // Node4
00259 
00260 TEM Node4<T>::Node4()
00261 :   parent(0), child(0), right(0), left(0)
00262 {}
00263 
00264 TEM Node4<T>::~Node4(){
00265 }
00266 
00267 
00268 TEM void Node4<T>::add(T * node){
00269     node->parent = (T *)this;
00270     
00271     if(child){
00272         T * last = child;
00273         while(last->right) last = last->right;
00274         
00275         last->right = node;
00276         node->left = last;
00277     }
00278     else{
00279         child = node;
00280     }
00281 }
00282 
00283 
00284 TEM void Node4<T>::remove(){
00285     if(left)        left->right = right;    // connect left to right, or...
00286     else if(parent) parent->child = right;  // connect parent to right
00287     if(right)       right->left = left;     // connect right to left
00288 }
00289 
00290 
00291 
00292 TEM void Node4<T>::setAsFirstChild(){
00293 
00294     if(left){   // i.e. not first child
00295     
00296         // connect neighbor siblings
00297         left->right = right;
00298         if(right) right->left = left;
00299         
00300         // insert in first child location
00301         parent->child->left = (T *)this;
00302         right = parent->child;
00303         left = 0;
00304         
00305         // update parent's link
00306         parent->child = (T *)this;
00307     }
00308 }
00309 
00310 
00311 TEM void Node4<T>::setAsLastChild(){
00312 
00313     if(right){  // i.e. not last child
00314     
00315         // connect neighbor siblings
00316         if(left)    left->right = right;
00317         else        parent->child = right;
00318         right->left = left;
00319         
00320         // insert in last child location
00321         T * last = right;
00322         while(last->right) last = last->right;
00323 
00324         last->right = (T *)this;
00325         right = 0;
00326         left = last;
00327     }
00328 }
00329 
00330 
00331 TEM T * Node4<T>::next(const T * terminal) const {
00332     
00333     T * node = (T *)this;
00334     
00335     if(node->child){
00336         node = node->child;
00337     }
00338     else if(node->right){
00339         node = node->right;
00340     }
00341     else{
00342         while(node != terminal && node->right == 0){
00343             node = node->parent;
00344         }
00345 
00346         if(node != terminal && node->right){
00347             node = node->right;
00348         }
00349     }
00350     
00351     if(node == terminal) return 0;
00352     
00353     return node;
00354 }
00355 
00356 
00357 //template <class T>
00358 //T * Node4<T>::nextBreadth(T * terminate){
00359 //  
00360 //  T * node = (T *)this;
00361 //  
00362 //  if(node->right){
00363 //      node = node->right;
00364 //  }
00365 //  else if(node->parent && node->parent->child){
00366 //  
00367 //  }
00368 //  
00369 //  if(node == terminate) return 0;
00370 //  
00371 //  return node;
00372 //}
00373 
00374 
00375 TEM void Node4<T>::print(const char * append){
00376     printf("%p%s", this, append);
00377 }
00378 
00379 
00380 TEM void Node4<T>::printDescendents(const char * append){
00381 
00382     T * node = (T *)this;
00383 
00384     do{
00385         T * p = node->parent;
00386         while(p != this->parent){ printf("  "); p = p->parent; }
00387         node->print("\n");
00388         node = node->next((T *)this);
00389     }while(node);
00390     
00391     printf("%s",append);
00392 }
00393 
00394 
00395 // Node4 helper sub-classes
00396 
00397 //#define TREE_OBJECT(name) name : public Node4<name>
00398 //
00399 //class TREE_OBJECT(TreeString){
00400 //public:
00401 //  TreeString(const char * str = "");          // from C string
00402 //  TreeString(const char * str, int length);   // from substring
00403 //
00404 //  string * value;
00405 //
00406 //  void print(char * append){ cout << *value << append; }
00407 //};
00408 //
00409 //inline TreeString::TreeString(const char * str){
00410 //  value = new string(str);
00411 //}
00412 //
00413 //inline TreeString::TreeString(const char * str, int length){
00414 //  value = new string(str, length);
00415 //}
00416 //
00417 //#undef TREE_OBJECT
00418 
00419 } // gam::
00420 
00421 #undef TEM
00422 #endif
00423