#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 { if (r < 0 || r >= numRows() || c < 0 || c >= numColumns()) throw out_of_range("Invalid indices"); 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) { if (r < 0 || r >= numRows() || c < 0 || c >= numColumns()) throw out_of_range("Invalid indices"); 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