/*
 * Copyright ©2026 Soham Pardeshi. All rights reserved.
 * Permission is hereby granted to students registered for University of
 * Washington CSE 333 for use solely during Summer Quarter 2026 for
 * purposes of the course. No other use, copying, distribution, or
 * modification is permitted without prior written consent. Copyrights
 * for third-party components of this work must be honored. Instructors
 * interested in reusing these course materials should contact the author.
 */

#include "IntArray.h"

// RAII: acquire the resource in the constructor.  The object's lifetime IS
// the buffer's lifetime.
IntArray::IntArray(size_t size) : size_(size) {
  data_ = new int[size_];
  for (size_t i = 0; i < size_; i++) {
    data_[i] = 0;
  }
}

// The destructor runs automatically when the object dies and releases what
// the object owns.  Clients never call delete[] by hand.
IntArray::~IntArray() {
  delete[] data_;
}

// Copy constructor: allocate a FRESH buffer, then copy the elements over, so
// each object owns its own array.  A shallow copy would share one buffer and
// double-free it.
IntArray::IntArray(const IntArray& other) : size_(other.size_) {
  data_ = new int[size_];
  for (size_t i = 0; i < size_; i++) {
    data_[i] = other.data_[i];
  }
}

// Copy assignment: guard against self-assignment, free the old buffer, then
// deep-copy the other object's buffer.
IntArray& IntArray::operator=(const IntArray& other) {
  if (this == &other) {  // self-assignment: a = a;
    return *this;
  }
  delete[] data_;  // free the old resource
  size_ = other.size_;
  data_ = new int[size_];
  for (size_t i = 0; i < size_; i++) {
    data_[i] = other.data_[i];
  }
  return *this;  // enables chaining: a = b = c;
}