// @(#)$Id: List.C,v 1.5 1999/04/11 15:57:36 leavens Exp $
// Lists as in LISP, implemented using the Procedural Data Abstraction idea.

#include "List.h"

// List
template <class T>
int List<T>::length() const throw()
{
  return is_null() ? 0 : 1 + tail()->length();
}

// Nil
template <class T>
Nil<T>::Nil() throw()
{
}

template <class T>
bool Nil<T>::is_null() const throw()
{
  return true;
}

template <class T>
T Nil<T>::head() const throw()
{
  abort();
  return (T)0;  // never reached
}

template <class T>
List<T>* Nil<T>::tail() const throw() 
{
  abort();
  return 0;     // never reached
}


// NonEmptyList
template <class T>
bool NonEmptyList<T>::is_null() const throw()
{
  return false;
}

template <class T>
T NonEmptyList<T>::head() const throw()
{
  return contents;
}

template <class T>
List<T>* NonEmptyList<T>::tail() const throw()
{
  return next_cell;
}


// ImmutableList
template <class T>
ImmutableList<T>::ImmutableList(T x, ImmutableList<T>* l) throw()
{
  contents = x;
  next_cell = l;
}

template <class T>
ImmutableList<T>::ImmutableList(T x, Nil<T>* l) throw()
{
  contents = x;
  next_cell = l;
}

