#include <cstring>
#include <iostream>
#include "section5a_fixed.h"

IntArrayList::IntArrayList()
  : capacity_(10), len_(0) {
  arr_ = new int[capacity_];
}
IntArrayList::IntArrayList(size_t capacity)
  : capacity_(capacity), len_(0) {
  arr_ = new int[capacity_];
}
IntArrayList::IntArrayList(const IntArrayList& rhs)
  : capacity_(rhs.capacity_), len_(rhs.len_) {
  arr_ = new int[capacity_];
  memcpy(arr_, rhs.arr_, len_ * sizeof(int));
}
IntArrayList::IntArrayList(const int* arr, size_t len)
  : capacity_(len * 2), len_(len) {
  arr_ = new int[capacity_];
  memcpy(arr_, arr, len * sizeof(int));
}
IntArrayList::~IntArrayList() {
  delete [] arr_;
}

size_t IntArrayList::len() const {
  return len_;
}

IntArrayList& IntArrayList::operator=(const IntArrayList& rhs) {
  if (this != &rhs) {
    len_ = rhs.len_;
    capacity_ = rhs.capacity_;
    delete [] arr_;
    arr_ = new int[capacity_];
    memcpy(arr_, rhs.arr_, len_ * sizeof(int));
  }
  return *this;
}

void IntArrayList::resize(size_t cap) {
  int* tmp = new int[cap];
  memcpy(tmp, arr_, len_ * sizeof(int));
  delete [] arr_;
  arr_ = tmp;
  capacity_ = cap;
}
void IntArrayList::operator+=(const IntArrayList& other) {
  if (len_ + other.len_ > capacity_) {
    resize((len_ + other.len_) * 2);
  }
  memcpy(arr_ + len_, other.arr_, other.len_ * sizeof(int));
  len_ += other.len_;
}
void IntArrayList::operator+=(int n) {
  if (len_ + 1 > capacity_) {
    resize((len_ + 1) * 2);
  }
  arr_[len_] = n;
  len_++;
}

int& IntArrayList::operator[](size_t indx) {
  if (indx < 0 || indx >= len_) {
    throw;
  }
  return arr_[indx];
}

std::ostream& operator<<(std::ostream& ostr, IntArrayList& rhs) {
  ostr << "[";
  if (rhs.len_ > 0) {
    for (size_t i = 0; i < rhs.len_ - 1; i++) {
      ostr << rhs.arr_[i] << ", ";
    }
    ostr << rhs.arr_[rhs.len_ - 1];
  }
  ostr << "]";
  return ostr;
}