// dimensiones.h
#if !defined( _DIMENSIONES_H_ )
#define _DIMENSIONES_H_
#include <iostream>
using namespace std;

//////////////////////////////////////////////////////////////////
// Clase para acumular las dimensiones de la matriz
class CDimensiones
{
    int *m_DimensionesMatriz;  // cada dimensión
    int m_nDimensiones;        // número de dimensiones

    // Asignar los valores adecuados a los datos miembro de un
    // objeto CDimensiones
    void Construccion(int nDims, int *pDims);
  public:
    // Sólo son utilizadas las dimensiones d1 a dn.
    // El resto se ignoran.
    CDimensiones(int n=0, int d1=0,int d2=0,int d3=0,
                 int d4=0,int d5=0,int d6=0)
    {
      int DimsMat[] = { d1, d2, d3, d4, d5, d6 };
      Construccion(n, DimsMat); // objeto CDimension
    }
    ~CDimensiones() { delete [] m_DimensionesMatriz; }

    // Número de dimensiones
    int nDimensiones() { return m_nDimensiones; }
    // Matriz de dimensiones
    const int *DimensionesMatriz() const
                  { return m_DimensionesMatriz; }
    // Total de elementos de la matriz multidimensional
    int TotalElementos() const;
    // Constructor copia.
    CDimensiones(const CDimensiones &x);
    // Asignación.
    CDimensiones &operator=(const CDimensiones &x);
};

// Constructor copia.
inline CDimensiones::CDimensiones(const CDimensiones &x)
{
  Construccion(x.m_nDimensiones, x.m_DimensionesMatriz);
}

// Asignación.
inline CDimensiones &CDimensiones::operator=(const CDimensiones &x)
{
  delete [] m_DimensionesMatriz;
  Construccion(x.m_nDimensiones, x.m_DimensionesMatriz);
  return *this;
}

// Construir un objeto CDimensiones para contener cada una de las
// dimensiones y el número de ellas.
void CDimensiones::Construccion(int nDims, int *pDims)
{
  int *dim = pDims;

  for (int i = nDims; i--; dim++)
    if (*dim < 1)
    {
      cerr << "Dimensión nula o negativa\n";
      // Asignar valores por omisión
      m_DimensionesMatriz = new int[m_nDimensiones = 1];
      m_DimensionesMatriz[0] = 1;
      return;
    }
  
  m_DimensionesMatriz = new int[m_nDimensiones = nDims];
  memcpy(m_DimensionesMatriz, pDims, nDims*sizeof(int));
}

// Total de elementos de la matriz multidimensional
int CDimensiones::TotalElementos() const
{
  int nElementos = m_DimensionesMatriz[0]; // total elementos
  int nDims = m_nDimensiones;              // contador
  int *dim = m_DimensionesMatriz + 1;      // siguiente dimensión

  while (--nDims) nElementos *= *dim++;

  return nElementos;
}
//////////////////////////////////////////////////////////////////

#endif // _DIMENSIONES_H_

