// -*- C++ -*-
//      Copyright 1993, Center for Computer Vision and Visualization,
//      University of Florida.  All rights reserved.

#ifndef IA_List_h_
#define IA_List_h_

#include "Deque.h"

static char IA_List_h_rcsid[] = "$Id: List.h,v 1.3 1994/04/27 18:26:09 rjj Exp $";

// $Log: List.h,v $
//Revision 1.3  1994/04/27  18:26:09  rjj
//Changed T operator[](int) const  to operator().
//
//Revision 1.2  1993/11/14  19:52:18  rjj
//Changed 'emptyp()' to 'empty()'.
//
//Revision 1.1  93/11/11  01:16:44  rjj
//Initial revision
//


// Note that this is NOT ment to provide the full functionality of
// Lisp lists.  It is ment to be available for things like lists of
// integers, doubles, points, images, etc.


template <class T> class IA_ListIter;   // forward declaration


template <class T>
class IA_List: protected IA_Deque<T> {
protected:
    IA_List(const IA_Deque<T>&);   // Implementation pragmatic

public:
    IA_List();

    IA_List(const IA_List<T>&);     // Copy of the List
    IA_List(T *vec, unsigned size); // where size = number of elements in vec

    IA_List(T v0);                  // constructing List with one element
    IA_List(T v0, T v1);
    IA_List(T v0, T v1, T v2);
    IA_List(T v0, T v1, T v2, T v3);
    IA_List(T v0, T v1, T v2, T v3, T v4);

    virtual ~IA_List() {};

    IA_List<T>&  operator= (const IA_List<T>&);

    T            operator() (unsigned) const;
    T&           operator[] (unsigned);
    

    int       empty() const;    // Is the List empty? 
    unsigned  length() const;  // yielding the number of elements in the List

    T         head() const;      // yielding the first element in the List
    void      tail(IA_List<T>& theTail); // sublist not including head()

    void      ins(T);

    void      del();
    void      delNth(unsigned);
    void      delValue(const T& aValueToDelete);

    void      reverse(IA_List<T>& theResult);
    void      sub(unsigned start_index, unsigned end_index,
		  IA_List<T>& theResult);

    friend
    void      concat (const IA_List<T>&, const IA_List<T>&,
		      IA_List<T>& theResult);

    friend class IA_ListIter<T>;
};



// The iterator assumes the list will not go out of scope while it is
//   in use.  To do so may be hazadous to your programs...

template <class T>
class IA_ListIter: protected IA_DequeIter<T> {
private:

public:

    IA_ListIter(const IA_List<T>& aList) : IA_DequeIter<T>(aList) { }

    int operator() (T& receptacle);
};

#endif
