1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// Array.h
// 2D Array implemented as a 1d array.
//
/* Ex:
* A 2D array like
* 1 2
* 3 4
*
* is represented interally here by
* 1 2 3 4
*
* myarray(0,0) returns 1,
* myarray(1,1) returns 4, etc.
*
*/
#ifndef PABLO_ARRAY_H
#define PABLO_ARRAY_H
#include <exception>
namespace exspace
{
template <typename T>
class Array
{
struct OutOfBounds : public std::exception
{
virtual const char* what() const throw()
{ return "Out of bounds index."; }
};
public:
typedef unsigned int uint_t;
// Construct a 2D array, size row x col.
Array(const uint_t& row, const uint_t& col)
: _rowSize(row), _colSize(col)
{ _ptr = new T[row*col]; }
// Clean up resources.
~Array()
{ delete[] _ptr; }
// Copy constructor.
Array(const Array& toCopy) //const
: _rowSize(toCopy._rowSize),
_colSize(toCopy._colSize)
// Not 100% sure about delete *this, but it would leak memory otherwise, right?
{ delete *this; this->_ptr = new T[_rowSize*_colSize]; }
uint_t GetRowSize() const
{ return _rowSize; }
uint_t GetColSize() const
{ return _colSize; }
// Assignment operator.
const Array& operator=(const Array&) const;
// Checks first if the array sizes are equal, then
// if every element in both arrays are equal.
bool operator==(const Array& rhs) const;
bool operator!=(const Array& rhs) const
{ return !(*this == rhs); }
// Access a value within the vector at the provided position (row, col).
T &operator() (uint_t row, uint_t col);
// Overloaded to return a const value as well.
const T &operator() (uint_t row, uint_t col) const;
private:
uint_t _rowSize;
uint_t _colSize;
T* _ptr;
};
template <typename T>
const Array<T>& Array<T>::operator=(const Array& rhs) const
{
// Prevent self assignment.
if (&rhs != this)
{
if (_rowSize != rhs._rowSize ||
_colSize != rhs._colSize)
{
delete[] _ptr;
_rowSize = rhs._rowSize;
_colSize = rhs._colSize;
_ptr = new T[_rowSize*_colSize];
}
for (int i=0; i<_rowSize*_colSize; i++)
_ptr[i] = rhs._ptr[i];
}
return *this;
}
template <typename T>
bool Array<T>::operator==(const Array& rhs) const
{
// Check if their dimensions are equal
if (_rowSize != rhs._rowSize ||
_colSize != rhs._colSize)
return false;
// Check each value for equality
for (int i=0; i<_rowSize*_colSize; i++)
{
if (_ptr[i] != rhs._ptr[i])
return false;
}
// If both are false, return true.
return true;
}
template <typename T>
const T& Array<T>::operator() (Array::uint_t row, Array::uint_t col) const
{
// If the requested position is within bounds,
// return the element there.
if (row < _rowSize && col < _colSize)
return _ptr[(col*_rowSize)+row];
else
throw OutOfBounds();
}
template <typename T>
T& Array<T>::operator() (Array::uint_t row, Array::uint_t col)
{
if (row < _rowSize && col < _colSize)
return _ptr[(col*_rowSize)+row];
else
throw OutOfBounds();
}
}
#endif // PABLO_ARRAY_H
|