// -*- coding: utf-8 -*- // Time-stamp: // Representation of m×n arrays with single array of size m×n // // Repd // +------------+ // | Rep | // |+----------+| // || nlin || // |+----------+| // || ncol || // |+----------+| // || refs || // |+----------+| Real array of T // +------------+ +-------------------+ // | p |--------->| | | | .... | | // +------------+ +-------------------+ #ifndef REPD_HPP #define REPD_HPP #include "rep.hpp" template class Repd : public Rep { public: // Constructor from dimensions Repd(int m, int n); // Access operator to a non-constant array virtual typename Rep::Line operator[](int i) override; // Access operator to a constant array virtual const typename Rep::Line operator[](int i) const override; // Destructor ~Repd(); private: // Clone virtual Repd* clone() const override; // Unidimentional array containing all elements. // Element [i,j] is at position p[i*ncol+j] T* p; }; // Constructor from dimensions template Repd::Repd(int m, int n) : Rep(m, n) { #ifdef TRACE cout << "Repd(" << m << ", " << n << ") : " << this << endl; #endif // Alloc the array if both dimensions are positive if (this->nlin > 0 && this->ncol > 0) p = new T[this->nlin * this->ncol]; else // Mark no allocation has occurred p = nullptr; } // Destructor template Repd::~Repd() { #ifdef TRACE cout << "~Repd() : " << this << endl; #endif // Free the array only if allocation has occurred if (p != nullptr) delete [] p; } // Clone template Repd* Repd::clone() const { // Create copy of representation Repd* tmp = new Repd(this->nlin, this->ncol); // Copy elements for(int i = 0; i < this->nlin * this->ncol; i++) tmp->p[i] = p[i]; return tmp; // Return copy } // Access operator to a non-constant array template typename Rep::Line Repd::operator[](int i) { if (0 <= i && i < this->nlin) return typename Rep::Line(p + i * this->ncol, this->ncol); else throw new exception(); } // Access operator to a constant array template const typename Rep::Line Repd::operator[](int i) const { if (0 <= i && i < this->nlin) return typename Rep::Line(p + i * this->ncol, this->ncol); else throw new exception(); } #endif