#ifndef MATRIX_PROXY_H #define MATRIX_PROXY_H #include "matrix.h" /***************************************************** * matrix_proxy class ****************************************************/ class matrix_proxy { private: matrix& M; // reference to the underlying source matrix const range rows; // copy of range describe extent of rows const range cols; // copy of range describing extent of columns public: matrix_proxy(matrix& src, const range& r, const range& c) : M(src), rows(r), cols(c) { } int numRows() const { return rows.size(); } int numColumns() const { return cols.size(); } // allows assignment from another matrix matrix_proxy& operator=(const matrix& other) { if (numRows() != other.numRows() || numColumns() != other.numColumns()) throw invalid_argument("Matrix dimensions must agree."); for (int r=0; r < numRows(); r++) for (int c=0; c < numColumns(); c++) (*this)(r,c) = other(r,c); return *this; } // read-only version of indexing operator double operator()(int r, int c) const { int actualRow = rows.start() + r*rows.stride(); int actualCol = cols.start() + c*cols.stride(); return M(actualRow, actualCol); } // write-access version of indexing operator double& operator()(int r, int c) { int actualRow = rows.start() + r*rows.stride(); int actualCol = cols.start() + c*cols.stride(); return M(actualRow, actualCol); } }; //-------------------------------------------------------- // define additional support for outputting matrix proxies //-------------------------------------------------------- ostream& operator<<(ostream& out, const matrix_proxy& m); #endif