
#include <iostream>
//#include <stdio>
using namespace std;

template <class T>
class Array
{
protected:
    T* data;
    unsigned int base;
    unsigned int length;
	unsigned int index;
public:
    Array();
    Array(unsigned int, unsigned int = 0);
    ~Array();

    Array (Array const&);
    Array& operator = (Array const&);

    T const& operator [] (unsigned int) const;
    T& operator [] (unsigned int);
    T& elementAt(int);
    T const* Data () const;
    unsigned int Base () const;
    unsigned int Length () const;

    void SetBase (unsigned int);
    void SetLength (unsigned int);
	void add(T elem);
};
template <class T>
Array<T>::Array () :
    data (new T [0]),
    base (0),
    length (0),
    index (0)
    {}

template <class T>
Array<T>::Array (unsigned int n, unsigned int m) :
    data (new T [n]),
    base (m),
    length (n),
    index (0)
    {}

template <class T>
Array<T>::Array (Array<T> const& array) :
    data (new T [array.length]),
    base (array.base),
    length (array.length),
	index (0)
{
    for (unsigned int i = 0; i < length; ++i)
	data [i] = array.data [i];
}

template <class T>
Array<T>::~Array ()
    { delete [] data; }

template <class T>
T const* Array<T>::Data () const
    { return data; }

template <class T>
unsigned int Array<T>::Base () const
    { return base; }

template <class T>
unsigned int Array<T>::Length () const
    { return length; }

template <class T>
T const& Array<T>::operator [] (unsigned int position) const
{
    unsigned int const offset = position - base;
	if (offset >= length){
	//throw out_of_range ("invalid position");
        //cout<<"invalid position"<<endl;
		return 1;
	}
	index = offset+1;
    return data [offset];
}
template <class T>
T& Array<T>::elementAt(int pos){
    return operator[](pos);
}

template <class T>
T& Array<T>::operator [] (unsigned int position)
{
    unsigned int const offset = position - base;
	if (offset >= length){
	//throw out_of_range ("invalid position");
		//cout<<"invalid position"<<endl;
	}
	index = offset+1;
    return data [offset];
}

template <class T>
void Array<T>::SetBase (unsigned int newBase)
    { base = newBase; }

template <class T>
void Array<T>::SetLength (unsigned int newLength)
{
    T* const newData = new T [newLength];
    unsigned int const min =
	length < newLength ? length : newLength;
    for (unsigned int i = 0; i < min; ++i)
	newData [i] = data [i];
    delete [] data;
    data = newData;
    length = newLength;
}
template <class T>
void Array<T>::add(T elem)
{
	if(index < length){
	    data[index] = elem;
	    index = index+1;
	}
	else{
		cout<<"Array index out of bounds"<<endl;
	}
}

/*int main(){
    Array <int> x(10);
	for(int i=0; i< 10; i++){
       x.add(i);
       cout <<x[i]<<" , ";
	}
	cout <<endl;
    //printf("test");
    //cout <<"Array init="<<x[0]<<endl;
    return 0;
}*/

