next up previous contents
Next: The While Block: Up: Remove a Node: Previous: GnodePtrBagManip Constructor:

The while loop:

Once the manipulator is instantiated, we are at the head cell of the collection of node pointers stored in the bag. Let's examine this code carefully: the while code is as follows:

  while(nodeMan){
    //there is a nodeMan.advance() used in this block to move 
    //to the next node  
    }

The Boolean Test:

The while loop can be entered as long as NodeMan evaluates true. The boolean test code is very similar to the boolean code used in iterators: we will see that advancing through the bag moves L to its next cell. Hence, we simply test to see if L is NULL. If so, we return false.

GnodePtrBagManip::operator const void *() const
{
  if( L==NULL) return (const void *)0;
  else return (const void *)1;
}

The Evaluator:

Since L is a GnodePtrBagLink pointer, the fragment

L->d_pointer_p;

gives us the node pointer stored in L.

Gnode *GnodePtrBagManip::operator()() const
{
  if( L!=NULL )
    return L->d_pointer_p;
  else
    return NULL;
}

The advance() Method:

To advance, we just move from L to its next pointer. Of course, once we hit the end of the bad, the next pointer is NULL.

void GnodePtrBagManip::advance()
{ 
  L = L->next();    
}

The remove() Method:

This method is the most complicated. As we discussed earlier, the cell removal must be done as usual in a list.

void GnodePtrBagManip::remove()
{
  GnodePtrBagLink *tmp = L; 
  L = L->next();
  
  //set pointers
  GnodePtrBagLink *Now = *d_addrLink_p;
  GnodePtrBagLink *Prev;
  
  if(tmp==Now){
    *d_addrLink_p = (*d_addrLink_p)->next();
    delete Now;
    }
  else{
    Prev = Now;
    Now = Now->next();
    while( !(Now==tmp) ){ //find L
      Prev = Now;
      Now = Now->next();    
      }    
    Prev->d_next_p = Now->next(); 
    delete Now;      
    }
}

Now note that without the local variable L we might write the following code (this is actually done in Lakos,  19!)

void GnodePtrBagManip::remove()
{
  GnodePtrBagLink *tmp = *d_addrLink_p;
  *d_addrLink_p = d_addrLink_p->next();
  delete tmp; 
}

Note the advance in the bag effectively removes the previous cell from the bag forever. This is not really what we want to do (this remember is a delete a cell from a linked list!) and the next cell from the previous cell is not properly reset.

So look at the while code again. The while loop test is on the boolean nodeMan and the advance method is used to step through the bag. Termination occurs when we step to the last cell whose next pointer is NULL which sets the boolean to false.

  while(nodeMan){
    //there is a nodeMan.advance() used in this block to move 
    //to the next node  
    }


next up previous contents
Next: The While Block: Up: Remove a Node: Previous: GnodePtrBagManip Constructor:
Jim Peterson
1999-05-17