/* $Id: matrix.h,v 1.3 1996/11/06 11:37:48 roitzsch Exp $ */

#ifndef MATRIX_TEMPLATE_H
#define MATRIX_TEMPLATE_H


#define CheckBoundsFlag  0


#define FORALL_ROWS(m,i)     for (i=(m).rl; i<=(m).rh; ++i)
#define FORALL_COLUMNS(m,i)  for (i=(m).cl; i<=(m).ch; ++i)

//-------------------------------------------------------------------------

#include <stdio.h>
#include <iostream.h>


template<class T>
 
class Matrix							 
{									 
  public:								 

    T**  row;						 
    int  rl, rh, cl, ch;					 
									 
    Matrix (int rl1, int rh1, int cl1, int ch1)			 
			      { allocate (rl1,rh1,cl1,ch1); }
    Matrix (int nr1, int nc1) { allocate (1,  nr1, 1, nc1); }	
    ~Matrix();


    int rLow()  const { return rl; }
    int rHigh() const { return rh; }
    int cLow()  const { return cl; }
    int cHigh() const { return ch; }

    void resize (int newrh, int newch);
    void resize (int newrl, int newrh, int newcl, int newch); 

    T* operator() (int i) 
    { 
	if (CheckBoundsFlag) checkBounds(i);
	return row[i]; 
    }
    T* operator() (int i) const
    { 
	if (CheckBoundsFlag) checkBounds(i);
	return row[i]; 
    }
    T& operator() (int i, int j)  
    { 
	if (CheckBoundsFlag) checkBounds(i,j);
	return row[i][j]; 
    }
    const T& operator() (int i, int j) const
    { 
	if (CheckBoundsFlag) checkBounds(i,j);
	return row[i][j]; 
    }
    
    int memSize();
    int size();

    void print() const;
    // friend ostream& operator<< (ostream& s, const Matrix<T>& mat);
    
    
  private:

    void allocate (int rl1, int rh1, int cl1, int ch1);		
    void checkBounds(int i, int j) const;
    void checkBounds(int i)        const;
	 
    Matrix(Matrix<T>& m);			// disallowed function!
    Matrix<T>& operator= (Matrix<T>& m);		// disallowed function!
    Matrix<T>& operator= (T a);			// disallowed function!
    void notImplemented(const char* s) const;
};
// ----------------------------------------------------------------------------

#if INCLUDE_TEMPLATE_DEFS
#include "matrix.c"
#endif
								 
#endif
