// matriz.h
#if !defined( _MATRIZ_H_ )
#define _MATRIZ_H_
#include "dimensiones.h"
#include "elemento_accedido.h"

//////////////////////////////////////////////////////////////////
// Plantilla de clase para construir matrices multidimensionales

template <class T> class CMatriz
{
    friend class CElementoAccedido<T>;

    T *m_pMatriz;   // matriz lineal de elementos de tipo T
    CDimensiones m_Dimensiones; // dimensiones de la matriz
  public:
    // Constructor
    CMatriz(int s1=0,int s2=0,int s3=0,int s4=0,int s5=0,int s6=0)
    {
      int DimsArr[] = { s1, s2, s3, s4, s5, s6 };
      int n = 6; // empiezo por el final para detectar, por ej, (4,0,5)
      while(n > 1 && DimsArr[n - 1] == 0) { n--; }
      m_Dimensiones = CDimensiones(n, s1, s2, s3, s4, s5, s6);
      m_pMatriz = new T[m_Dimensiones.TotalElementos()];
    }
    // Constructor copia
    CMatriz(const CMatriz<T> &x);
    // Devuelve un objeto que contiene una referencia al objeto CMatriz
    // y los subíndices del elemento accedido
    CElementoAccedido<T> operator[](int subind)
    {
      return CElementoAccedido<T>(*this, subind);
    }
    // Asignación
    CMatriz<T> &operator=(const CMatriz<T> &x);
};

// Constructor copia
template <class T> inline CMatriz<T>::CMatriz(const CMatriz<T> &x) :
m_Dimensiones(x.m_Dimensiones)
{
   size_t tam = x.m_Dimensiones.TotalElementos();
   m_pMatriz = new T[tam];
   memcpy(m_pMatriz, x.m_pMatriz, tam*sizeof(T));
}

// Asignación
template <class T>
inline CMatriz<T> &CMatriz<T>::operator=(const CMatriz<T> &x)
{
   m_Dimensiones = x.m_Dimensiones;
   delete [] m_pMatriz;
   size_t tam = x.m_Dimensiones.TotalElementos();
   m_pMatriz = new T[tam];
   memcpy(m_pMatriz, x.m_pMatriz, tam*sizeof(T));
   return *this;
}
//////////////////////////////////////////////////////////////////

#endif // _MATRIZ_H_

