// This may look like C code, but it is really -*- C++ -*-
//
//  Copyright (c) University of Aizu 1994
//

// Wrappers protect against including this file more than once

#ifndef List_h
#define List_h 1

//  This is a "container class". It is used to handle a collection of
//  objects of the same type. There are many ways to implement container
//  classes. This is just one of the easiest.

//  The constructor for lists is a bit special. In order to be able to
//  read lists, the read functions need a buffer for the list elements,
//  not just to temporarily store the elements, but mainly to use the
//  correct functions to read the elements. In order to achieve this,
//  a "sample" of the list element is stored with the list. This sample
//  has to be created prior to constructing the list, and passed on to
//  the constructor.

//  The correct way to declare a list containing objects of the type 
//  "Element" is:
//
//  List list(new Element);
//
//  The sample will be deleted when the list is destroyed.


#include <Base.h>

//  Listable objects are objects that can be handled by the "List" class.
//  Listable objects require a duplication function. 

//  List element:
class Listable: public Base {
public:
  friend class List;

  // constructor 
  Listable();
  Listable(const Listable&);

  // destructor
  virtual ~Listable(void);

  // access
  Listable *next(void) const;
  Listable *prev(void) const;
  List     *list(void) const;

  // modification
  Listable *insertBefore(const Listable& aListable);
  Listable *insertAfter(const Listable& aListable);

  // "virtual" copy constructor...
  virtual Listable *duplicate(void) const = 0;

private:
  Listable *next_, *prev_;
  List *list_;
};


class List: public Base {
public:
  friend class Listable;

  List(Listable* aSample = 0);
  List(const List& aList);
  virtual ~List(void);

  //  this is a real class, so make it's name known.
  virtual char *classname(void) const;

  //  modify list
  Listable *add(const Listable& aListable);
  void clear(void);   // the whole list

  // copy lists
  List& operator=(const List& list);

  //  access list
  Listable* head(void) const;
  Listable* last(void) const;

  //  I/O. 
  virtual IOstatus readContents(void);
  virtual IOstatus writeContents(void) const;

private:
  Listable *head_;
  Listable *sample_;
};

// End of wrapper
#endif
// End of file
