Chapter Index | Slide Index | Frames [ Windows ] | Narrative On | <- prev | next -> |

Implementing class TList < T >

// stand-alone functions

template <typename T> 
bool operator == (const TList<T>& L1, const TList<T>& L2)
{
  // assuming Size() is O(1); otherise must be modified
  if (L1.Size() != L2.Size())
    return 0;

  TList<T>::Iterator I1(L1), I2(L2);
  while (I1.Valid() && I2.Valid())
  {
    if (*(I1++) != *(I2++))
      return 0;
  }
  return 1;
}

template <typename T> 
bool operator != (const TList<T>& L1, const TList<T>& L2)
{
  // TBS
}

template <typename T> 
ostream& operator << (ostream& os, const TList<T>& L2)
{
  L2.Display(os);
  return os;
}

// constructors and assignment

template <typename T>
TList<T>::TLink::TLink (const T& Tval)  :  value(Tval), prevLink(0), nextLink(0)
{}

template <typename T> 
TList<T>::TList ()  :  firstLink(0), lastLink(0), size(0) // assuming size
// default constructor
{}

template <typename T> 
TList<T>::TList (const TList<T>& L)
// copy constructor
{
  Clone(L);
}

template <typename T> 
TList<T>::~TList ()
// destructor
{
  Clear();
} 

template <typename T> 
TList<T>& TList<T>::operator = (const TList<T>& L)
// assignment overload
// Note that assignment behaves like a unary operator that builds a copy
// of the input (right side) object and returns a pointer to the copy. 
// The copy is built as "this", i.e., the current object. 
// This makes assignment associate correctly:
// a = b = c equivalent to a = (b = c).
{
  if (this != &L)   // it would be a disaster to assign to self!
  {
    // First, destroy the existing list.
    Clear();
    // then build a clone as *this
    Clone(L);
  }
  return *this;
} // end assignment operator =

template <typename T> 
bool TList<T>::PushFront (const T& t)
// Insert t at the front (first) position.
{
  // TBS
} // end PushFront()

template <typename T> 
bool TList<T>::PushBack (const T& t)
// Insert t at the back (last) position.
{
  // TBS
} // end PushBack()

template <typename T> 
bool TList<T>::Insert (TListIterator<T>& I, const T& t)
// Insert t at I
{
  // TBS
  // call the Push methods when they apply
  // Insert at back if iterator is not valid

  // Insert at front if iterator is at front

  // iterator is valid and not at front
  // 1. create new element

  // 2. link new element into the list

  // 3. adjust size (if present)

  // 4. leave I at new entry and return
} // end Insert((I,t))

template <typename T> 
TListIterator<T> TList<T>::Insert (const T& t)
// Insert t at default location (back)
{
  TListIterator<T> I = End();
  Insert(I,t);
  return I;
}

template <typename T>
bool TList<T>::PopFront ()
{
  // TBS
} // end PopFront()

template <typename T>
bool TList<T>::PopBack ()
{
  // TBS
} // end PopBack()

template <typename T> 
bool TList<T>::Remove (TListIterator<T>& I)
// Remove item at I
{
  // TBS
  // we call the Pop() methods when they apply,
  // to make sure of consistent interaction with ends of list

  // first deal with the invalid iterator case

  // now we have a valid iterator and non-void list
  // deal with the cases I.currLink == firstLink, lastLink

  // at this point, we're removing a link that's neither first nor last
  // 1: remember link to be removed, and advance iterator

  // 2: unlink oldLink from the list

  // 3: delete old link, adjust size (if present), and return

} // end Remove(I)

template <typename T> 
unsigned int  TList<T>::Remove (const T& t)
// Remove all copies of t
{
  // TBS
  // use iterator I and call Remove(I)
  // be sure to take into account the similarity between Remove(I) and ++I
} // end Remove(t)

template <typename T> 
void TList<T>::Clear ()
// Deletes all links in the TList
// and restores pointer values and size (if present) to 0
{
  // TBS
} // end Clear()

template <typename T> 
unsigned int TList<T>::Size () const
{
  // TBS
}

template <typename T> 
bool TList<T>::Empty () const
{
  // TBS
}

template <typename T> 
T& TList<T>::Front () const
{
  // TBS
}

template <typename T> 
T& TList<T>::Back () const
{
  // TBS
}

template <typename T> 
TListIterator<T>  TList<T>::Begin () const
{
  Iterator I;
  I.currLink = firstLink;
  return I;
}

template <typename T> 
TListIterator<T>  TList<T>::End () const
{
  Iterator I;
  return I;
}

template <typename T> 
TListIterator<T>  TList<T>::rBegin () const
{
  // TBS
}

template <typename T> 
TListIterator<T>  TList<T>::rEnd () const
{
  // TBS
}

template <typename T>
void TList<T>::Display (ostream& os, char ofc) const
{
  TList<T>::Iterator I;
  if (ofc == '\0')
    for (I = Begin(); I.Valid(); ++I)
      os << *I;
  else
    for (I = Begin(); I.Valid(); ++I)
      os << *I << ofc;
}

// protected method

template <typename T>
void TList<T>::Clone (const TList<T>& L)
// Makes *this a clone of L;
// used by = (assignment operator) and copy constructor.
{
  // first copy the static data and initialize the pointers

  // then the dynamic data in the non-empty case

} // end Clone()

<- prev | next -> | Top of Page | 8. A Generic List Class and Linked Lists - 18 of 19