#ifndef ARRAY_HH
#define ARRAY_HH

template<class T>
class Array {
public:
  Array(int size, T default_value) : _size(size) {
	  _arr = new T[_size] ;
	  _default = default_value;
  }

  Array(const Array& other) : _size(other._size) {
    _arr = new T[other._size] ;
	_default = other._default ;

    // Copy elements
    for (int i=0 ; i<_size ; i++) {
      _arr[i] = other._arr[i] ;
    }
  }

  ~Array() {
    delete[] _arr ;
  }


  Array& operator=(const Array& other) 
  {
    if (&other==this) return *this ;
    if (_size != other._size) {
      resize(other._size) ;
    }
    for (int i=0 ; i<_size ; i++) {
      _arr[i] = other._arr[i] ;
    }
    return *this ;
  }

  T& operator[](int index) {
	if ( index > _size ) {
		resize(index+1);
	}

    return _arr[index] ;
  }
  const T& operator[](int index) const {
    return _arr[index] ;
  }

  int size() const { return _size ; }

  void resize(int newSize) {
    // Allocate new array
    T* newArr = new T[newSize] ;

    // Copy elements
    for (int i=0 ; i<_size ; i++) {
      newArr[i] = _arr[i] ;
    }

	for ( int i=_size ; i<newSize ; i++ ) {
		newArr[i] = _default;
	}

    // Delete old array and install new one
    delete[] _arr ;
    _size = newSize ;
    _arr = newArr ;
  }


private:
  int _size ;
  T* _arr ;
  T _default ;
} ;

#endif
