// list.cpp

#include <iostream>
#include <assert.h>
using namespace std;

#define SIZE 16

template <class T>
class List
{
private:
  T body[SIZE];
    int lastIndex; // records the last index used
public:
    List(); // creates an empty list
    ~List();
    void clear();
    void display();
    T at(int index); // return the element at index index 
    void insertAt(T val, int index);
    T removeAt(int index);
    int size();
    int indexOf(T val); // return the index where val
                        // is first found, or -1 if 
                        // val is not in the list
};

template <class T>
List<T>::List()
{
    clear();
}

template <class T>
List<T>::~List()
{
    // do nothing
}

template <class T>
void List<T>::clear()
{
    lastIndex = -1; // i.e. empty list
}

template <class T>
void List<T>::display()
{
    cout << "[";
    for (int i = 0; i < lastIndex; ++i)
    {
        cout << body[i] << ",";
    }
    if (lastIndex >= 0)
    {
        cout << body[lastIndex];
    }
    cout << "]" << endl;
}

template <class T>
T List<T>::at(int index)
{
    return body[index];
}

template <class T>
void List<T>::insertAt(T val, int index)
{
    assert(size() < SIZE);
    assert(index <= size());
    for (int i = lastIndex; i >= index; --i)
    {
        body[i + 1] = body[i];
    }
    body[index] = val;
    lastIndex++;
}

template <class T>
T List<T>::removeAt(int index)
{
    assert(size() > 0);
    assert(index >= 0 && index < size());
    T temp = body[index];
    for (int i = index; i < lastIndex; ++i)
    {
        body[i] = body[i + 1];
    }
    lastIndex--;
    return temp;
}

template <class T>
int List<T>::size()
{
    return lastIndex + 1;
}

template <class T>
int List<T>::indexOf(T val)
{
    int i = 0;
    while (i <= lastIndex)
    {
        if (body[i] == val)
        {
            return i;
        }
        i++;
    }
    return -1;
}

int main()
{
    List<double> *list = new List<double>();
    list->insertAt(4.2, 0);
    list->insertAt(5.1, 1);
    list->insertAt(8.6, 2);
    list->insertAt(3.3, 1);
    list->display();
    double x = list->removeAt(0);
    cout << x << " was removed from the list." << endl;
    list->display();
    int j = list->indexOf(8.6);
    if (j != -1)
    {
        cout << "8.6 was found at index " << j << endl;
    }
}