#ifndef MATRIX_H
#define MATRIX_H
#include <string>
struct matrixError
{
matrixError( std::string r) : reason(r) { }
const std::string reason;
};
struct indexError : public matrixError
{
indexError( int i, int j) : row(i), col(j), matrixError("Bad index") { }
int row;
int col;
};
template <class T>
class matrix
{
public:
matrix( int i, int j );
matrix( const matrix &other);
~matrix();
matrix operator=( const matrix &other);
int rows() const { return x; }
int cols() const { return y; }
T& at( int i, int j) throw(indexError);
T at( int i, int j) const throw(indexError);
T& operator()( int i, int j);
T operator()( int i, int j) const;
matrix operator+=( const matrix &other);
matrix operator+( const matrix &other);
private:
int x;
int y;
T *v;
void copy( const matrix &other);
void check( int i, int j) const throw(indexError);
};
template <class T>
matrix<T>::matrix( int i, int j)
{
x = i;
y = j;
v = new T[x*y];
}
template <class T>
matrix<T>::matrix( const matrix &other)
{
copy( other);
}
template <class T>
matrix<T>::~matrix()
{
delete [] v;
}
template <class T>
matrix<T> matrix<T>::operator=( const matrix &other)
{
if ( this != &other )
{
delete [] v;
copy( other);
}
return *this;
}
template <class T>
void matrix<T>::copy( const matrix &other)
{
x = other.x;
y = other.y;
v = new T[x*y];
for ( int i = 0; i < x*y; ++i )
v[i] = other.v[i];
}
template <class T>
void matrix<T>::check( int i, int j) const throw( indexError )
{
if ( ( 0 <= i && i < x ) && ( 0 <= j && j < y ) )
/* ok */ ;
else
throw indexError(i,j);
}
template <class T>
T& matrix<T>::at( int i, int j) throw(indexError)
{
check(i,j);
return operator()(i,j);
}
template <class T>
T matrix<T>::at( int i, int j) const throw( indexError)
{
check(i,j);
return operator()(i,j);
}
template <class T>
T& matrix<T>::operator()( int i, int j)
{
return v[i*y + j];
}
template <class T>
T matrix<T>::operator() ( int i, int j) const
{
return v[i*y + j];
}
template <class T>
matrix<T> matrix<T>::operator+=( const matrix &other)
{
for ( int i = 0; i < x*y; ++i )
v[i] += other.v[i];
return *this;
}
template <class T>
matrix<T> matrix<T>::operator+( const matrix &other)
{
matrix<T> temp( *this );
temp += other;
return temp;
}
#endif /* MATRIX_H */