/* Copyright (c) 2001 by the Institute for Computer Science,               */
/* Alberts-Ludwigs-University of Freiburg, Germany.                        */
/* All Rights Reserved.  This software is for educational purposes only.   */
/* Permission is given to distribute this code provided that this intro-   */
/* ductory message is not removed and no monies are exchanged.             */
/* No guarantee is expressed or implied by the distribution of this code.  */
/* Software written by Alberto Lluch Lafuente and Stefan Edelkamp.         */
/* References:                                                             */
/* - Stefan Edelkamp, Alberto Lluch Lafuente and Stefan Leue,              */
/*   Directed Explicit Model Checking with HSF-SPIN, to appear in:         */
/*   Proc. 8th International SPIN Workshop on Model Checking Software,     */
/*   Springer LNCS 2057, Toronto, May 2001                                 */
/* - Stefan Edelkamp, Alberto Lluch Lafuente and Stefan Leue,              */
/*   Protocol Verification with Heuristic Search,                          */
/*   Proc. AAAI Spring Symposium on Model-Based Validation of Inteligence, */
/*   AAAI, Stanford, April 2001.                                           */
/* Send bug-reports or questions to: lafuente@informatik.uni-freiburg.de   */

#ifndef _ARRAY_
#define _ARRAY_

#include<assert.h>

template<class T>
class Array {

private:
  int row_dim, col_dim;
  T** element;
public:
  Array() { row_dim = col_dim = 0; element=0; }
  Array(int rdim, int cdim);
  Array(int rdim, int cdim, T* initval);
  Array(int rdim, int cdim, T singleval);
  Array(const Array<T>&);
  ~Array();
  inline int Row() const { return row_dim; }
  inline int Col() const { return col_dim; }
  Array<T>& operator=(const Array<T>&);
  T* operator[](int i) { return element[i]; }

  print() const {
    int i,j;
    for(i=0;i<row_dim;i++) {
      for(j=0;j<col_dim;j++) {
//	cout << "(" << i << "," << j << ") =";
	cout <<  element[i][j];
	cout << " ";
      }
      cout << endl;
    }
  }
};

template<class T>
Array<T>::Array(int rdim, int cdim) {
  int i,j;
  row_dim = rdim; 
  col_dim = cdim;
  element = new T* [row_dim];
  for(i=0;i<rdim;i++) element[i] = new T[col_dim];
  for(i=0;i<rdim;i++)
    for(j=0;j<cdim;j++)
      element[i][j] = 0;
}

template<class T>
Array<T>::Array(int rdim, int cdim,T singleval) {
  int i,j;
  row_dim = rdim; 
  col_dim = cdim;
  element = new T* [row_dim];
  for(i=0;i<rdim;i++) element[i] = new T[col_dim];
  for(i=0;i<rdim;i++)
    for(j=0;j<cdim;j++)
      element[i][j] = singleval;
}

template<class T>
Array<T>::Array(int rdim, int cdim,T* initval) {
  int i,j;
  row_dim = rdim; 
  col_dim = cdim;
  element = new T* [row_dim];
  for(i=0;i<rdim;i++) element[i] = new T[col_dim];
  for(i=0;i<rdim;i++)
    for(j=0;j<cdim;j++)
      element[i][j] = *(initval + (cdim * i + j));
}

template<class T>
Array<T>::Array(const Array<T>& m) {
  int i,j; 
  row_dim = m.row_dim; 
  col_dim = m.col_dim;
  element = new T* [row_dim];
  for(i=0;i<row_dim;i++) element[i] = new T[col_dim];
  for(i=0;i<row_dim;i++)
    for(j=0;j<col_dim;j++)
      element[i][j] = m.element[i][j];
}

template<class T>
Array<T>::~Array() {
  int i;
  for(i=0;i<row_dim;i++) delete [] element[i];
  delete [] element;
}

template<class T>
Array<T>& Array<T>::operator=(const Array<T>& m) {
  int i,j; 
  row_dim = m.row_dim; 
  col_dim = m.col_dim;
  element = new T* [row_dim];
  for(i=0;i<row_dim;i++) element[i] = new T[col_dim];
  for(i=0;i<row_dim;i++)
    for(j=0;j<col_dim;j++)
      element[i][j] = m.element[i][j];
  return *this;
}

#endif //







