// FICHIER : Tableau_4D.cc
// CLASSE : Tableau_4D


// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL  : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.


#include <iostream>
using namespace std;
#include <stdlib.h>


#include "Tableau_4D.h"


Tableau_4D::Tableau_4D ()
// Constructeur par defaut
{
	
	dim1=0;
	dim2=0;
	dim3=0;
	dim4=0;
	t=NULL;
	
};

Tableau_4D::Tableau_4D (int d1,int d2,int d3,int d4,double val)
// Constructeur utile quand les quatre dimensions ainsi qu'une 
// eventuelle valeur d'initialisation sont connues 
{
	
	if ( ( d1<0 ) || ( d2<0 ) || ( d3<0 ) || ( d4<0 ) )
	{
		cout << "\nErreur : taille(s) invalide(s) !\n";
		cout << "TABLEAU_4D::TABLEAU_4D(int ,int ,int ,int ,double ) \n";
		exit(1);
	};
	if ( ( d1==0 ) || ( d2==0 ) || ( d3==0 ) || ( d4==0 ) )
	// cas ou une des dimensions est nulle : initialisation identique
	// a l'appel du constructeur par defaut
	{
		dim1=0;
		dim2=0;
		dim3=0;
		dim4=0;
		t=NULL;
	}
	else
	// autres cas
	{
		dim1=d1;
		dim2=d2;
		dim3=d3;
		dim4=d4;
		t=new double [d1*d2*d3*d4]; // allocation dynamique de la memoire
		Initialise(val); // initialisation des composantes a val
	};
	
};

Tableau_4D::Tableau_4D (const Tableau_4D& tab)
// Constructeur de copie
{
	
	if ( tab.dim1==0 )
	// cas ou le tableau copie est vide : initialisation 
	// identique a l'appel du constructeur par defaut
	{
		dim1=0;
		dim2=0;
		dim3=0;
		dim4=0;
		t=NULL;
	}
	else
	{
		dim1=tab.dim1;
		dim2=tab.dim2;
		dim3=tab.dim3;
		dim4=tab.dim4;
		t=new double [dim1*dim2*dim3*dim4]; // allocation dynamique de la memoire
		double* ptr1=t;
		double* ptr2=tab.t;
		for (int i=0;i<dim1;i++)
		{
			for (int j=0;j<dim2;j++)
			{
				for (int k=0;k<dim3;k++)
				{
					for (int l=0;l<dim4;l++)
					{
						(*ptr1++)=(*ptr2++); // copie des composantes du tableau tab
					}; // endfor l
				}; // endfor k
			}; // endfor j
		}; // endfor i
	};
	
};

Tableau_4D::~Tableau_4D ()
// Destructeur (N.B. : Apres l'appel de ce destructeur le tableau est identique
// a ce qu'il aurait ete a la suite d'un appel du constructeur par defaut)
{
	
	Libere();
	
};

void
Tableau_4D::Initialise (double val)
// Initialisation des composantes du tableau a quatre dimensions
{
	
	double* ptr=t;
	for (int i=0;i<dim1;i++)
	{
		for (int j=0;j<dim2;j++)
		{
			for (int k=0;k<dim3;k++)
			{
				for (int l=0;l<dim4;l++)
				{
					(*ptr++)=val; // initialisation des composantes a val
				}; // endfor l
			}; // endfor k
		}; // endfor j
	}; // endfor i
		
};
	
void 
Tableau_4D::Libere ()
// Apres l'appel de cette methode le tableau est identique a ce qu'il
// aurait ete a la suite d'un appel du constructeur par defaut
{
	
	if ( dim1>0 )
		delete [] t; // desallocation de la place memoire
	else
	{
		if ( t!=NULL )
		{
			cout << "\nErreur de liberation de la place memoire\n";
			cout << "TABLEAU_4D::LIBERE() \n";
			exit(1);
		}
	};
	t=NULL;
	dim1=0;
	dim2=0;
	dim3=0;
	dim4=0;
	
};


Tableau_4D& 
Tableau_4D::operator= (const Tableau_4D& tab)
// Surcharge de l'operateur = : egalite entre deux tableaux a quatre dimensions
{
	
	if ( t!=NULL ) Libere(); // cas ou le tableau se trouvant a gauche du signe =
							// n'est pas vide : desallocation de ce tableau
	if ( tab.dim1==0 )
	// cas ou le tableau se trouvant a droite du signe = est vide : initialisation
	// identique a l'appel du constructeur par defaut
	{
		dim1=0;
		dim2=0;
		dim3=0;
		dim4=0;
		t=NULL;
	}
	else 
	// autres cas
	{
		dim1=tab.dim1;
		dim2=tab.dim2;
		dim3=tab.dim3;
		dim4=tab.dim4;
		t=new double [dim1*dim2*dim3*dim4]; // allocation de la place memoire
		double* ptr1=t;
		double* ptr2=tab.t;
		// copie des elements du tableau se trouvant a droite dans le tableau se trouvant
		// a gauche du signe d'affectation
		for (int i=0;i<dim1;i++)
		{
			for (int j=0;j<dim2;j++)
			{
				for (int k=0;k<dim3;k++)
				{
					for (int l=0;l<dim4;l++)
					{
						(*ptr1++)=(*ptr2++); // copie des composantes du tableau tab
					}; // endfor l
				}; // endfor k
			}; // endfor j
		}; // endfor i
	};
	return (*this);
	
};
