/** @(#) mathpos/array2dpos.h */ #ifndef ARRAY2DPOS_H #define ARRAY2DPOS_H //---------------------------------------------------------------------------- #include <iostream> #include <string> #include <stdexcept> // runtime_exception using namespace std; /** * Reservar memoria. * No hace operaciones aritmeticas. * Entrada y salida de arreglos. * @author Omar Posada Villarreal * @version 1.1, 24/04/2002 * @version 1.0, 13/04/2002 */ template <class TC> class Array2DPos { //---------------------------------------------------------------------------- private: /** Apuntador a [firstRow][firstCol]. */ TC **pCorner; TC **pCenterCol; /** Apuntador a [0][0]. */ TC **pOrigin; /** Numero de renglones. */ int row; int col; /** Indice del primer renglon */ int firstRow; int firstCol; int lastRow; int lastCol; //---------------------------------------------------------------------------- public: // constructor, ~, friend----------------------------------------------------- /** * Reserva memoria para un arreglo bidimensional que permite indices negativos. * DUDA Si firstRow, firstCol de signos contrarios, * asignacion sin implementar * Uso: * Array2DPos<double> M(n, n); * @param theFirstRow [-N, +N] theFirstRow <= theLastRow * @param theFirstCol [-N, +N] theFirstCol <= theLastCol * @param theLastRow [-N, +N] * @param theLastCol [-N, +N] */ // templates solo en *.h Array2DPos(int theFirstRow, int theLastRow, int theFirstCol, int theLastCol) throw (invalid_argument){ // valida if ((theFirstRow > theLastRow) || (theFirstCol > theLastCol)){ throw invalid_argument("Array2DPos: indices invertidos"); } firstRow = theFirstRow; firstCol = theFirstCol; lastRow = theLastRow; lastCol = theLastCol; // Num de reng y col row = lastRow - firstRow + 1; col = lastCol - firstCol + 1; // pCorner pCorner = new TC*[row]; int i; for (i = 0; i < row; ++i) { pCorner[i] = new TC[col]; } // pOrigin pCenterCol = new TC*[row]; for (i = 0; i < row; ++i) { pCenterCol[i] = &(pCorner[i][ -firstCol]); } pOrigin = &(pCenterCol[ -firstRow]); // IMPORTANTE Previene underflow del apuntador pOrigin // si first > 0, pOrigin < pCorner if ((firstRow > 0) && (firstCol > 0)) { if (pOrigin > pCorner) { throw runtime_exception( "Array2DPos: apuntador ArrayOrigin negativo."); } } // DUDA Si firstRow, firstCol de signos contrarios, // asignacion sin implementar if ( (firstRow * firstCol) < 0 ) { throw runtime_exception("Array2DPos: falta implementar."); } } Array2DPos(int theRows, int theColumns) throw (invalid_argument) { if ((theRows < 1) || (theColumns < 1)) { throw invalid_argument("Array2DPos: indices negativos"); } Array2DPos(0, theRows - 1, 0, theColumns - 1); } /** * Libera memoria de un arreglo bidimensional de double. * @param row Numero de renglones. */ // templates solo en *.h ~Array2DPos() { deleteArray(); } /** Libera memoria. */ void deleteArray() { delete[] pOrigin; delete[] pCenterCol; int i; for (i = 0; i < row; ++i) { delete[] pCorner[i]; } delete []pCorner; //cout << "} ~Array2DPos()"; } // inline--------------------------------------------------------------------- inline TC **getArrayOrigin() const { return pOrigin; } inline int getRows() const { return row; } inline int getColumns() const { return col; } inline int getFirstRow() const { return firstRow; } inline int getLastRow() const { return lastRow; } inline int getFirstColumn() const { return firstCol; } inline int getLastColumn() const { return lastCol; } /** Abreviaciones */ inline int gR() const { return row; } inline int gC() const { return col; } inline int gFR() const { return firstRow; } inline int gLR() const { return lastRow; } inline int gFC() const { return firstCol; } inline int gLC() const { return lastCol; } // operator------------------------------------------------------------------- /** Checa indices. */ TC operator()(int indRow, int indCol) throw (invalid_argument) { if ( (indRow < firstRow) || (indRow > lastRow) || (indCol < firstCol) || (indCol > lastCol) ) { throw invalid_argument("operator(): indices fuera de rango."); } return pOrigin[indRow][indCol]; } // public--------------------------------------------------------------------- /** Muestra en salida estandar los elementos. Separados. Col:\t, Reng:\n. */ void print() { int i, j; for (i = 0; i < row; ++i) { for (j = 0; j < col; ++j) { cout << pCorner[i][j] << "\t"; } cout << endl; } } /** Asigna ceros a todos los elementos. */ void clean() { int i, j; for (i = 0; i < row; ++i) { for (j = 0; j < col; ++j) { pCorner[i][j] = static_cast<TC>(0); } } } }; // } Array2DPos------------------------------------------------------------ #endif // Fin------------------------------------------------------------------------