// ----------------------------------------------------------------------------
//
// Copyright (C) Columbia University, 1994. All Rights Reserved.
// Sameer A. Nene, Shree K. Nayar, Hiroshi Murase
//
// See file LICENSE for details of software license agreement.
//
// ----------------------------------------------------------------------------
//
// list.h
//
// Author:               Sameer Nene
// Date:                 05/24/94
// Version:              1.0
// Modification History:
// Bugs:
//
//
// Classes:
//   Link
//   List
//   ListIter
//   ListManip
//
// Notes:
//   
// ----------------------------------------------------------------------------

#ifndef LIST_INCLUDED
#define LIST_INCLUDED

#ifdef __GNUC__

#pragma interface

#endif

#include <iostream.h>

// forward class declarations

template<class Type> class ListIter;
template<class Type> class ListManip;

template<class Type> class Link {

  // Private members

  Type d_data;
  Link<Type> *d_next_p;

  // Links cannot be copied or assigned

  Link(const Link<Type>&);
  Link<Type>& operator=(const Link<Type>&);

  // Public members
  
public:

  // Construct & Destroy
  
  Link(Link<Type> **addLinkPtr, const Type &data);
  ~Link() {}			
  
  // Modifiers
  
  void setData(const Type &data);
  void setNext(Link<Type> *link);
  Link<Type>*& getNextRef(); // generally a bad practice
  
  // Accessors
  
  Type getData() const;
  Link<Type>* getNext() const;

};

template<class Type> class List {

  // Private members
  
  int d_length;
  Link<Type> *d_head_p;

  // Friends
  
  friend ListIter<Type>;
  friend ListManip<Type>;

  // Public members
  
public:

  // Construct & Destroy

  List();
  List(const List<Type>&);
  ~List();

  // Modifiers
  
  List<Type>& operator=(const List<Type> &list);
  List<Type>& operator+=(const Type &i);  
  List<Type>& operator+=(const List<Type> &list); 
  List<Type>& prepend(const Type &i);
  List<Type>& prepend(const List<Type> &list); 

  // Accessors
  
  int length() const;

};

template<class Type> ostream& operator<<(ostream& o, const List<Type>& list);

template<class Type> class ListIter {

  // Private Data

  Link<Type> *d_current_p;

  // Public Members
  
public:

  // Construct and Destroy

  ListIter(const List<Type> &list);
  ListIter(const ListIter<Type> &iter);
  ~ListIter() {}

  // Modifiers
  ListIter<Type>& operator=(const ListIter<Type> &iter);
  void operator++();

  // Accessors
  operator const void* () const;
  Type operator()() const;

};

template<class Type> class ListManip {

  // Private Data

  List<Type> *d_list_p;
  Link<Type> **d_current_p;
  
  // Links cannot be copied or assigned

  ListManip(const ListManip<Type> &manip);	  
  ListManip<Type>& operator=(const ListManip<Type> &manip);

  // Public Members

public:
  // Construct and Destroy
  ListManip(List<Type> *list);
  ~ListManip() {}

  // Modifiers
  void operator++();
  void insert (const Type &data);
  void remove ();

  // Accessors
  operator const void *() const;
  Type operator()() const;

};

#endif
