#include "Array2.h" #include // Default constructor Array2::Array2() : _ownData(false), _nrows(0), _ncols(), _buffer(0), _rows(0) { } // Size/array constructor Array2::Array2(int nrows, int ncols, long* data) : _ownData(false), _nrows(0), _ncols(), _buffer(0), _rows(0) { resize(nrows, ncols, data); } // Copy constructor Array2::Array2(const Array2 & source) : _nrows(source._nrows), _ncols(source._ncols) { _ownData = true; allocateMemory(); *this = source; } // Destructor Array2::~Array2() { deallocateMemory(); } // Assignment operator Array2 & Array2::operator=(const Array2 & source) { int nrows = _nrows < source._nrows ? _nrows : source._nrows; int ncols = _ncols < source._ncols ? _ncols : source._ncols; for (int i=0; i < nrows; ++i) { for (int j=0; j < ncols; ++j) { (*this)[i][j] = source[i][j]; } } return *this; } // Equals operator bool Array2::operator==(const Array2 & other) const { if (_nrows != other._nrows) return false; if (_ncols != other._ncols) return false; for (int i=0; i < _nrows; ++i) { for (int j=0; j < _ncols; ++j) { if ((*this)[i][j] != other[i][j]) return false; } } return true; } // Length accessors int Array2::nrows() const { return _nrows; } int Array2::ncols() const { return _ncols; } // Resize array void Array2::resize(int nrows, int ncols, long* data) { if (nrows < 0) throw std::invalid_argument("Array2 nrows less than 0"); if (ncols < 0) throw std::invalid_argument("Array2 ncols less than 0"); if (nrows == _nrows && ncols == _ncols) return; deallocateMemory(); _nrows = nrows; _ncols = ncols; if (!data) { allocateMemory(); } else { _ownData = false; _buffer = data; allocateRows(); } } void Array2::resize(int nrows, int ncols) { resize(nrows, ncols, nullptr); } // Set item accessor Array1 & Array2::operator[](int i) { if (i < 0 || i > _nrows) throw std::out_of_range("Array2 row index out of range"); return _rows[i]; } // Get item accessor const Array1 & Array2::operator[](int i) const { if (i < 0 || i > _nrows) throw std::out_of_range("Array2 row index out of range"); return _rows[i]; } // String output std::string Array2::asString() const { std::stringstream result; result << "[ "; for (int i=0; i < _nrows; ++i) { if (i > 0) result << " "; result << (*this)[i].asString(); if (i < _nrows-1) result << "," << std::endl; } result << " ]" << std::endl; return result.str(); } // Get view void Array2::view(int* nrows, int* ncols, long** data) const { *nrows = _nrows; *ncols = _ncols; *data = _buffer; } // Private methods void Array2::allocateMemory() { if (_nrows * _ncols == 0) { _ownData = false; _buffer = 0; _rows = 0; } else { _ownData = true; _buffer = new long[_nrows*_ncols]; allocateRows(); } } void Array2::allocateRows() { _rows = new Array1[_nrows]; for (int i=0; i < _nrows; ++i) { _rows[i].resize(_ncols, &_buffer[i*_ncols]); } } void Array2::deallocateMemory() { if (_ownData && _nrows*_ncols && _buffer) { delete [] _rows; delete [] _buffer; } _ownData = false; _nrows = 0; _ncols = 0; _buffer = 0; _rows = 0; }