// List.h -- generic lists
// 
// Author: Ian.Piumarta@INRIA.Fr
// 
// Last edited: 2000-12-04 15:43:07 by piumarta on emilia.rd.wdi.disney.com


#ifndef _j_List_h
#define _j_List_h


#include "debug.h"


class ListLink
{
public:
  ListLink *next;
  inline ListLink(ListLink *nextLink= 0) : next(nextLink) {}
};


template <class _elt_t>
class List
{
public:

  typedef _elt_t elt_t;

  elt_t *list;

public:

  inline List(void)
    {
      list= 0;
    }

  ~List(void)
    {
      while (list != 0)
	{
	  elt_t *nextElt= list->next;
	  delete list;
	  list= nextElt;
	}
      assert(list == 0);
    }

  inline bool isEmpty(void) const
    {
      return list == 0;
    }

  inline elt_t *add(elt_t *elt)
    {
      elt->next= list;
      list= elt;
      return elt;
    }

  elt_t *remove(elt_t *elt)
    {
      if (list == elt)
	{
	  list= elt->next;
	  return elt;
	}
      for (elt_t *pos= list;  pos != 0;  pos= pos->next)
	{
	  if (pos->next == elt)
	    {
	      pos->next= elt->next;
	      return elt;
	    }
	}
      fatal("element not found in list");
      return elt;
    }

  elt_t *removeFirst(void)
    {
      assert(list != 0);
      elt_t *first= list;
      list= first->next;
      return first;
    }
};


// this is ugly, but ANSI won't let me use (__typeof__(anInstance))::typedefName

#define listDo(LIST, VAR) \
  typedef __typeof__(LIST) VAR##_List_t; \
  for (VAR##_List_t::elt_t *VAR= (LIST).list;  VAR != 0;  VAR= VAR->next)


#endif // _j_List_h
