//===------------ Matrix_Fernando.cpp - Printing prototype ----------------===//
//
//              Register Allocation via Coloring of Chordal Graphs 
//
// This is a matrix (bidimensional array) abstract data type that uses
// templates to improve reusability.
//
// Date: May 27th, 2006
//
//===----------------------------------------------------------------------===//
//
// This file implements the matrix abstract data type. I have decided not to
// overload the [] operator in order to state clearly that this is an object.
// In this way, the values of the matrix must be manipulated with the get and
// set methods.
// Usage example:
// Matrix_Fernando<int> matrix(nrows, ncols);
// Matrix_Fernando<bool> matrix(nrows, ncols);
//
//===----------------------------------------------------------------------===//

#include <vector>

template<typename T> class Matrix_Fernando {

    public:
        /// constructor method
        Matrix_Fernando(unsigned nrows, unsigned ncols) : data_ (nrows) {
            assert( (nrows > 0 && ncols > 0) && "Matrix bound error" );
            for (unsigned i = 0; i < nrows; ++i) {
                data_[i].resize(ncols);
            }
        }

        /// return the element in given row and column. I opted for declaring
        /// the methods as inline functions so the compiler can try to
        /// optimize them whenever possible. This may result in big code size
        /// though.
        inline T get(unsigned row, unsigned col) {
            assert( (row < nrows() && col < ncols()) && "Matrix bound error" );
            return data_[row][col];
        }

        /// set the value of the element in the given row and column
        inline void set(unsigned row, unsigned col, T value) {
            assert( (row < nrows() && col < ncols()) && "Matrix bound error" );
            data_[row][col] = value; 
        }

        /// number of rows in this matrix
        inline unsigned nrows() const {
            return data_.size();
        }

        /// number of columns in this matrix
        inline unsigned ncols() const {
            return data_[0].size();
        }

    private:
        /// stores the bidimensional arrays in a single dimensional data
        /// structure.
        std::vector< std::vector<T> > data_;
};
