174 lines
3.2 KiB
C++
174 lines
3.2 KiB
C++
#include "Array2.h"
|
|
#include <sstream>
|
|
|
|
// 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;
|
|
}
|