895 lines
27 KiB
C++
895 lines
27 KiB
C++
// FICHIER : Tableau_T.h
|
|
// CLASSE : Tableau_T
|
|
|
|
// 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/>.
|
|
|
|
|
|
/************************************************************************
|
|
* DATE: 23/01/97 *
|
|
* $ *
|
|
* AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
|
|
* $ *
|
|
* PROJET: Herezh++ *
|
|
* $ *
|
|
************************************************************************
|
|
* BUT: La classe Tableau_T permet de declarer des tableaux de *
|
|
* longueur determinee et dont les composantes sont du type T fixe *
|
|
* a la declaration d'un objet de cette classe. L'operateur = doit *
|
|
* etre surcharge pour les objets de la classe T. *
|
|
* L'allocation memoire est dynamique et permet de declarer des *
|
|
* tableaux de tailles indifferentes. *
|
|
* $ *
|
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
|
|
* *
|
|
* VERIFICATION: *
|
|
* *
|
|
* ! date ! auteur ! but ! *
|
|
* ------------------------------------------------------------ *
|
|
* ! ! ! ! *
|
|
* $ *
|
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
|
|
* MODIFICATIONS: *
|
|
* ! date ! auteur ! but ! *
|
|
* ------------------------------------------------------------ *
|
|
* $ *
|
|
************************************************************************/
|
|
|
|
#ifndef TABLEAU_T_H
|
|
#define TABLEAU_T_H
|
|
|
|
|
|
//#include "Debug.h"
|
|
#include <iostream>
|
|
#include <stdlib.h>
|
|
#include <list>
|
|
|
|
using namespace std; //introduces namespace std
|
|
|
|
#include "Sortie.h"
|
|
#include <iomanip>
|
|
#include <string>
|
|
|
|
|
|
/** @defgroup Les_Tableaux_generiques
|
|
*
|
|
* BUT: groupe des tableaux génériques: typiquement des templates, mais pas seulement
|
|
*
|
|
*
|
|
* \author Gérard Rio
|
|
* \version 1.0
|
|
* \date 23/01/97
|
|
* \brief groupe des tableaux génériques: typiquement des templates, mais pas seulement
|
|
*
|
|
*/
|
|
|
|
/// @addtogroup Les_Tableaux_generiques
|
|
/// @{
|
|
///
|
|
|
|
|
|
template <class T>
|
|
class Tableau
|
|
{
|
|
|
|
// surcharge de l'operator d'ecriture
|
|
friend ostream & operator << (ostream & sort, const Tableau<T> & tab)
|
|
{ // tout d'abord un indicateur donnant le type
|
|
sort << "Tableau :taille= " << tab.taille << " ";
|
|
for (int i=0;i<tab.taille;i++)
|
|
{ sort << setprecision(nb_diggit_double_calcul) << tab.t[i] ; sort << " "; }
|
|
// sort << "\n";
|
|
return sort;
|
|
}
|
|
|
|
// affichage du premier élément pour les messages d'erreur
|
|
friend void Affiche_premier_elem(ostream &sort , const Tableau<T> & tab )
|
|
{ if (tab.taille > 0)
|
|
{sort << "\n le premier element du tableau pour info: ";
|
|
sort << tab.t[0] ;
|
|
sort << endl;};
|
|
}
|
|
|
|
|
|
public :
|
|
|
|
|
|
// CONSTRUCTEURS :
|
|
|
|
// Constructeur par defaut
|
|
Tableau ();
|
|
|
|
// Constructeur fonction de la taille du tableau
|
|
Tableau (int nb);
|
|
|
|
// Constructeur fonction de la taille du tableau et d'une
|
|
// valeur d'initialisation pour les composantes
|
|
Tableau (int nb,T val);
|
|
|
|
// Constructeur fonction de la taille du tableau et d'une
|
|
// référence: pas facile à faire car ensuite on manipule des pointeurs de références !!
|
|
// bref on ne sait pas ce que l'on fait , dans ce cas il vaut mieux utiliser
|
|
// un tableau de pointeur de la grandeur en question
|
|
|
|
// Constructeur fonction d'un tableau de composantes de type T
|
|
Tableau (int nb,T* tab);
|
|
|
|
// Constructeur de copie
|
|
Tableau (const Tableau<T> & tab);
|
|
|
|
|
|
// DESTRUCTEUR :
|
|
|
|
virtual ~Tableau ();
|
|
|
|
|
|
// METHODES :
|
|
|
|
inline int Taille () const
|
|
// Retourne la taille du tableau
|
|
{ return taille; };
|
|
|
|
// Retourne la ieme composante du tableau : acces en lecture et ecriture
|
|
T& operator() (int i) const;
|
|
|
|
// cas particulier ou l'on ne veut pas modifier les valeurs
|
|
const T val_const(int i) const;
|
|
const T& ref_const(int i) const;
|
|
|
|
// Surcharge de l'operateur !=
|
|
// Renvoie 1 si les deux tableaux ne sont pas egaux
|
|
// Renvoie 0 sinon
|
|
int operator!= (const Tableau<T>& tab) const;
|
|
|
|
// Surcharge de l'operateur ==
|
|
int operator== (const Tableau<T>& tab) const ;
|
|
|
|
// Surcharge de l'operateur d'affectation =
|
|
Tableau<T>& operator= (const Tableau<T>& tab);
|
|
|
|
// Change la taille du tableau (la nouvelle taille est n)
|
|
void Change_taille (int n);
|
|
// Change la taille du tableau (la nouvelle taille est n)
|
|
// et initialisation de toutes les valeurs, anciennes et nouvelles à tb
|
|
void Change_taille (int n,const T& tb);
|
|
|
|
// Enleve la ieme composante du tableau
|
|
void Enleve (int i);
|
|
|
|
// Enleve toutes les composantes du tableau dont la valeur est val
|
|
void Enleve_val (T val);
|
|
|
|
// Permet de desallouer l'ensemble des elements du tableau
|
|
void Libere ();
|
|
|
|
// initialisation d'un tableau à partir d'une liste
|
|
// premier du tableau == premier de la liste
|
|
void Init_from_list(const std::list<T> & liste );
|
|
|
|
// opération inverse: remplissage d'une liste à partir du tableau
|
|
// premier de la liste == premier du tableau
|
|
void Init_list(std::list<T> & liste );
|
|
|
|
// opération de lecture sur un flot d'entrée
|
|
// les données sont le type puis la dimension puis les datas
|
|
istream & Entree(istream &);
|
|
|
|
// les données sont le type puis la dimension puis les datas
|
|
// ici il n'y a pas redimentionnement du tableau si la taille est suffisante
|
|
istream & Entree_sans_redim(istream &);
|
|
|
|
// lectures sur le flot si la taille du tableau est identique ou supérieure à celle lue
|
|
// retour d'un pointeur nulle
|
|
// sinon, si la taille lue est supérieure à la taille du tableau actuellement existant
|
|
// il y a création d'un nouveau tableau de même type avec la taille adéquate
|
|
// et retour d'un pointeur sur le nouveau tableau
|
|
Tableau<T> * New_en_lecture_si_taille_superieur_a_lire(istream &);
|
|
|
|
// opération d'écriture non formatée
|
|
// les données sont le type la dimension puis les datas, chacun
|
|
// séparé par un espace
|
|
ostream & Sortir(ostream &) const ;
|
|
// idem mais sans retour chariot à la fin
|
|
ostream & Sortir_sansRet(ostream &) const;
|
|
|
|
// test si la valeur passée en argument apartient au tableau
|
|
// ramène 0 si ne contient pas
|
|
// ramène l'indice dans le tableau de la grandeur si appartenance
|
|
int Contient(const T& e) const;
|
|
|
|
// initialisation avec la valeur passée en argument
|
|
bool Inita(const T& e) ;
|
|
|
|
|
|
protected :
|
|
|
|
int taille; // taille du tableau
|
|
T* t; // pointeur sur les composantes du tableau
|
|
// on définit ici le nombre de diggit pour l'affichage de réel double
|
|
static int nb_diggit_double_calcul; //=17;
|
|
|
|
|
|
};
|
|
/// @} // end of group
|
|
|
|
// cas de la surcharge de la lecture : il y a deux cas a considérer
|
|
// 1) cas d'élément constant : dans ce cas la lecture est une erreur
|
|
// 2) cas d'élément non constant : lecture permise
|
|
// les deux fonctions sont en dehors de la classe car sinon dans la classe il y a pris en compte
|
|
// du fait d'avoir des éléments constants ou non ce qui n'a pas l'air évident à traité sinon par
|
|
// deux classes différentes
|
|
|
|
template <class T>
|
|
int Tableau<T>::nb_diggit_double_calcul=17;
|
|
|
|
|
|
template <class T>
|
|
// surcharge de l'operator de lecture d'élément non constant
|
|
istream & operator >> (istream & entree, Tableau<T> & tab)
|
|
{ // vérification du type
|
|
string type;
|
|
entree >> type;
|
|
if (type != "Tableau")
|
|
{Sortie (1);
|
|
return entree;
|
|
};
|
|
int dim; entree >> type >> dim;
|
|
int tabtaille = tab.Taille();
|
|
if (dim != tabtaille)
|
|
tab.Change_taille(dim);
|
|
for (int i=1;i<=dim;i++)
|
|
entree >> tab(i);
|
|
return entree;
|
|
}
|
|
|
|
//================================= def des differents elements ==================
|
|
|
|
|
|
template <class T>
|
|
inline Tableau<T>::Tableau ()
|
|
// Constructeur par defaut
|
|
{ taille=0;
|
|
t=NULL;
|
|
}
|
|
|
|
|
|
template <class T>
|
|
inline Tableau<T>::Tableau (int nb)
|
|
// Constructeur devant etre utilise quand la dimension nb du tableau est connu
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if ( nb<0 )
|
|
// cas ou la taille selectionnee est negative
|
|
{ cout << "\nErreur : taille invalide !\n";
|
|
cout << "TABLEAU_T::TABLEAU_T(int ) \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
if ( nb==0 )
|
|
// cas ou la taille selectionnee est nulle : initialisation identique a
|
|
// l'appel du constructeur par defaut
|
|
{ taille=0;
|
|
t=NULL;
|
|
}
|
|
else
|
|
// autres cas
|
|
{ taille=nb;
|
|
t=new T [taille]; // allocation de la place memoire
|
|
T* ptr=t;
|
|
for (int i=0;i<taille;i++)
|
|
// initialisation des composantes a l'aide de l'attribut statique defaut
|
|
// (*ptr++)=defaut;
|
|
(*ptr++)= T();
|
|
};
|
|
}
|
|
|
|
template <class T>
|
|
inline Tableau<T>::Tableau (int nb, T val)
|
|
// Constructeur permettant de creer un tableau dont toutes les composantes
|
|
// sont egales a val
|
|
// N.B: La valeur de l'attribut defaut est fixee a val
|
|
{ // initialisation de l'element defaut
|
|
#ifdef MISE_AU_POINT
|
|
if ( nb<0 )
|
|
// cas ou la taille selectionnee est negative
|
|
{ cout << "\nErreur : taille invalide !\n";
|
|
cout << "TABLEAU_T::TABLEAU_T(int ,T ) \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
if ( nb==0 )
|
|
// cas ou la taille selectionnee est nulle : initialisation identique a
|
|
// l'appel du constructeur par defaut
|
|
{ taille=0;
|
|
t=NULL;
|
|
}
|
|
else
|
|
// autres cas
|
|
{ taille=nb;
|
|
t=new T [taille]; // allocation de la place memoire
|
|
T* ptr=t;
|
|
for (int i=0;i<taille;i++)
|
|
// initialisation des composantes a val
|
|
(*ptr++)=val;
|
|
};
|
|
}
|
|
|
|
template <class T>
|
|
inline Tableau<T>::Tableau (int nb,T* tab)
|
|
// Constructeur permettant de creer un tableau de taille nb dont les composantes
|
|
// sont initialisees a l'aide des valeurs de tab
|
|
// N.B.: tab doit avoir au moins nb composantes (aucun test n'est realise pour le
|
|
// verifier !!!)
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if ( nb<0 )
|
|
// cas ou la taille selectionnee est negative
|
|
{ cout << "\nErreur : taille invalide !\n";
|
|
cout << "TABLEAU_T::TABLEAU_T(int ,T* ) \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
if ( nb==0 )
|
|
// cas ou la taille selectionnee est nulle : initialisation identique a
|
|
// l'appel du constructeur par defaut
|
|
{
|
|
taille=0;
|
|
t=NULL;
|
|
}
|
|
else
|
|
// autres cas
|
|
{
|
|
taille=nb;
|
|
t=new T [taille]; // allocation de la place memoire
|
|
T* ptr1=t;
|
|
T* ptr2=tab;
|
|
for (int i=0;i<taille;i++)
|
|
// copie des composantes du tableau tab dans le tableau declare
|
|
(*ptr1++)=(*ptr2++);
|
|
};
|
|
}
|
|
|
|
template <class T>
|
|
inline Tableau<T>::Tableau (const Tableau<T>& tab)
|
|
// Constructeur de copie
|
|
{ if ( tab.taille==0 )
|
|
// cas ou le tableau copie est vide : initialisation identique a l'appel
|
|
// du constructeur par defaut
|
|
{ t=NULL;
|
|
taille=0;
|
|
}
|
|
else
|
|
// autres cas
|
|
{ t=new T [tab.taille]; // allocation de la place memoire
|
|
T* ptr1=t;
|
|
T* ptr2=tab.t;
|
|
for (int i=0;i<tab.taille;i++)
|
|
// copie des composantes du tableau tab dans le tableau declare
|
|
(*ptr1++)=(*ptr2++);
|
|
taille=tab.taille;
|
|
};
|
|
}
|
|
|
|
template <class T>
|
|
inline Tableau<T>::~Tableau ()
|
|
// 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(); }
|
|
|
|
template <class T> void
|
|
inline Tableau<T>::Change_taille (int n)
|
|
// Permet de modifier la taille du tableau
|
|
// N.B. : Si la nouvelle taille est superieure a l'ancienne alors le tableau est
|
|
// complete par defaut
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if ( n<0 )
|
|
// cas ou la taille selectionnee est negative
|
|
{ cout << "\nErreur : taille invalide !\n";
|
|
cout << "TABLEAU_T::CHANGE_TAILLE(int ) \n";
|
|
cout << " NB: taille actuelle = " << taille << " ";
|
|
Sortie(1);
|
|
}
|
|
#endif
|
|
if ( n == taille ) // taille identique , on ne fait rien
|
|
return;
|
|
if ( n==0 )
|
|
// cas ou la taille selectionnee est nulle : initialisation identique a
|
|
// l'appel du constructeur par defaut
|
|
{
|
|
taille=0;
|
|
if ( t!= NULL) delete [] t;
|
|
t=NULL;
|
|
return ;
|
|
};
|
|
T* tempo;
|
|
tempo=new T [n];
|
|
T* ptr1=t;
|
|
T* ptr2=tempo;
|
|
if ( n<=taille )
|
|
// cas ou la taille selectionnee est inferieure a la taille d'origine
|
|
{
|
|
for (int i=0;i<n;i++)
|
|
// copie des composantes du tableau d'origine dans le tableau pointe par tempo
|
|
(*ptr2++)=(*ptr1++);
|
|
}
|
|
else if ( n>taille )
|
|
// cas ou la taille selectionnee est superieure a la taille d'origine
|
|
{
|
|
for (int i=0;i<taille;i++)
|
|
// copie des composantes du tableau d'origine dans le tableau pointe par tempo
|
|
(*ptr2++)=(*ptr1++);
|
|
for (int i=taille;i<n;i++)
|
|
// initialisation des composantes supplementaires a l'aide de l'element par defaut
|
|
///(*ptr2++)=defaut;
|
|
(*ptr2++)=T();
|
|
};
|
|
delete [] t; // desallocation du tableau pointe par t
|
|
t=tempo; // affectation du pointeur t au pointeur tempo
|
|
taille=n;
|
|
|
|
}
|
|
|
|
template <class T> void
|
|
inline Tableau<T>::Change_taille (int n,const T& tb)
|
|
// Change la taille du tableau (la nouvelle taille est n)
|
|
// et initialisation de toutes les valeurs, anciennes et nouvelles à tb
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if ( n<0 )
|
|
// cas ou la taille selectionnee est negative
|
|
{ cout << "\nErreur : taille invalide !\n";
|
|
cout << "TABLEAU_T::CHANGE_TAILLE(int ) \n";
|
|
cout << " NB: taille actuelle = " << taille << " ";
|
|
Sortie(1);
|
|
}
|
|
#endif
|
|
if ( n == taille ) // taille identique , on ne fait que l'initialisation
|
|
{ T* ptr2= t;
|
|
for (int i=0;i<n;i++)
|
|
// copie des composantes à tb
|
|
(*ptr2++)=tb;
|
|
return;
|
|
}
|
|
|
|
if ( n==0 )
|
|
// cas ou la taille selectionnee est nulle : initialisation identique a
|
|
// l'appel du constructeur par defaut
|
|
{
|
|
taille=0;
|
|
if ( t!= NULL) delete [] t;
|
|
t=NULL;
|
|
return ;
|
|
};
|
|
T* tempo;
|
|
tempo=new T [n];
|
|
T* ptr2=tempo;
|
|
if ( n<=taille )
|
|
// cas ou la taille selectionnee est inferieure a la taille d'origine
|
|
{
|
|
for (int i=0;i<n;i++)
|
|
// copie des composantes du tableau d'origine dans le tableau pointe par tempo
|
|
(*ptr2++)=tb;
|
|
}
|
|
else if ( n>taille )
|
|
// cas ou la taille selectionnee est superieure a la taille d'origine
|
|
{
|
|
for (int i=0;i<n;i++)
|
|
// copie des composantes à tb
|
|
(*ptr2++)=tb;
|
|
};
|
|
delete [] t; // desallocation du tableau pointe par t
|
|
t=tempo; // affectation du pointeur t au pointeur tempo
|
|
taille=n;
|
|
}
|
|
|
|
template <class T>
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
T& Tableau<T>::operator() (int i) const
|
|
// Retourne la ieme composante du tableau : acces en lecture et ecriture
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if ( (i<1) || (i>taille) )
|
|
{ cout << "\nErreur : composante inexistante !, nb demande = " << i << '\n';
|
|
cout << "T& TABLEAU_T::OPERATOR() (int ) \n";
|
|
cout << "\n pour info: taille actuelle du tableau = " << taille << " ";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
return t[i-1];
|
|
}
|
|
|
|
// cas particulier ou l'on ne veut pas modifier les valeurs
|
|
template <class T>
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
const T Tableau<T>::val_const(int i) const
|
|
//const T& Tableau<T>::operator() (int i) const
|
|
// Retourne la ieme composante du tableau : acces en lecture seulement
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if ( (i<1) || (i>taille) )
|
|
{ cout << "\nErreur : composante inexistante !, nb demande = " << i << '\n';
|
|
cout << "T TABLEAU_T::OPERATOR() (int ) const \n";
|
|
cout << "\n pour info: taille actuelle du tableau = " << taille << " ";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
T retour = t[i-1];
|
|
return retour;
|
|
}
|
|
|
|
// Retourne la référence constante à la ieme composante du tableau : acces en lecture seulement
|
|
template <class T>
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
const T& Tableau<T>::ref_const(int i) const
|
|
//const T& Tableau<T>::operator() (int i) const
|
|
// Retourne la ieme composante du tableau : acces en lecture seulement
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if ( (i<1) || (i>taille) )
|
|
{ cout << "\nErreur : composante inexistante !, nb demande = " << i << '\n';
|
|
cout << "T TABLEAU_T::OPERATOR() (int ) const \n";
|
|
cout << "\n pour info: taille actuelle du tableau = " << taille << " ";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
return t[i-1];
|
|
}
|
|
|
|
template <class T>
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
int Tableau<T>::operator!= (const Tableau<T>& tab) const
|
|
// Surcharge de l'operateur !=
|
|
// Renvoie 1 si les deux tableaux ne sont pas egaux
|
|
// Renvoie 0 sinon
|
|
{ if ( (*this)==tab ) // test de l'egalite des deux tableaux a l'aide
|
|
// de l'operateur surcharge ==
|
|
return 0;
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
template <class T> void
|
|
inline Tableau<T>::Enleve (int i)
|
|
// Enleve la ieme composante du tableau en decrementant la taille
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if ( (i<1) || (i>taille) )
|
|
{
|
|
cout << "\nErreur : composante inexistante "<<i<< " !\n";
|
|
cout << "TABLEAU_T::ENLEVE(int ) \n";
|
|
cout << "\n pour info: taille actuelle du tableau = " << taille << " ";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
T* tempo;
|
|
tempo=new T [taille-1];
|
|
T* ptr1=t;
|
|
T* ptr2=tempo;
|
|
for (int j=0;j<i-1;j++)
|
|
// copie des elements du tableau pointe par t dans le tableau pointe par tempo
|
|
// du 1er au (i-1)eme element
|
|
(*ptr2++)=(*ptr1++);
|
|
ptr1++; // saut du ieme element du tableau pointe par t
|
|
for (int j=i;j<taille;j++)
|
|
// copie des elements du tableau pointe par t dans le tableau pointe par tempo
|
|
// du (i+1)eme au dernier element
|
|
(*ptr2++)=(*ptr1++);
|
|
delete [] t; // desallocation du tableau pointe par t
|
|
t=tempo; // affectation du pointeur t au pointeur tempo
|
|
taille=taille-1;
|
|
}
|
|
|
|
template <class T> void
|
|
inline Tableau<T>::Enleve_val (T val)
|
|
// Enleve les composantes du tableau egales a val en decrementant la taille
|
|
{
|
|
|
|
T* tempo;
|
|
tempo=new T [taille];
|
|
T* ptr1=t;
|
|
T* ptr2=tempo;
|
|
int nouvel_taille=taille;
|
|
for (int j=0;j<taille;j++)
|
|
// boucle sur les composantes du tableau
|
|
{
|
|
if ( (*ptr1)!=val )
|
|
// l'objet pointe n'est pas egal a val
|
|
(*ptr2++)=(*ptr1++);
|
|
else
|
|
// l'objet pointe est egal a val, saut de celui-ci
|
|
{
|
|
ptr1++;
|
|
nouvel_taille=nouvel_taille-1;
|
|
};
|
|
};
|
|
|
|
#ifdef MISE_AU_POINT
|
|
if ( nouvel_taille==taille )
|
|
{
|
|
cout << "\nErreur : absence de la composante cherchee !\n";
|
|
cout << "TABLEAU_T::ENLEVE_VAL(T ) \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
delete [] t; // desallocation du tableau pointe par t
|
|
t=tempo; // affectation du pointeur t au pointeur tempo
|
|
taille=nouvel_taille;
|
|
|
|
}
|
|
|
|
template <class T> void
|
|
inline Tableau<T>::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 ( taille>0 )
|
|
delete [] t; // desallocation du tableau pointe par t
|
|
else
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if ( t!=NULL )
|
|
{ cout << "\nErreur de liberation de la place memoire\n";
|
|
cout << "TABLEAU_T::LIBERE() \n";
|
|
// Affiche_premier_elem( cout);
|
|
Sortie(1);
|
|
}
|
|
#endif
|
|
};
|
|
t=NULL;
|
|
taille=0;
|
|
}
|
|
|
|
template <class T> void
|
|
inline Tableau<T>::Init_from_list(const std::list<T> & liste )
|
|
// initialisation d'un tableau à partir d'une liste
|
|
{ int tail_liste = liste.size(); // récup de la tail de la liste
|
|
typename std::list<T>::const_iterator ili,ilifin=liste.end();
|
|
Change_taille(tail_liste);
|
|
int i=0;
|
|
for (ili=liste.begin();ili!=ilifin;ili++,i++)
|
|
t[i] = (*ili);
|
|
}
|
|
|
|
template <class T> void
|
|
inline Tableau<T>::Init_list(std::list<T> & liste )
|
|
// initialisation d'une liste à partir du tableau
|
|
// premier de la liste == premier du tableau
|
|
{ liste.clear(); // on initialise la liste
|
|
// on balaie le tableau et on remplit la liste
|
|
T* ptr1=t;
|
|
for (int i=0;i<taille;i++)
|
|
liste.push_back(*ptr1++);
|
|
}
|
|
|
|
|
|
template <class T>
|
|
inline Tableau<T> & Tableau<T>::operator= (const Tableau<T> & tab)
|
|
// Surcharge de l'operateur = : realise l'egalite entre deux tableaux de pointeurs
|
|
{
|
|
// on essaie d'optimiser un peu
|
|
// -- si les tableaux sont identiques en taille, on ne réaffecte pas
|
|
// on ne fait que la recopie
|
|
if (taille == tab.taille)
|
|
{ // on n'examine que si la taille est non nulle
|
|
if (taille != 0)
|
|
{ T* ptr1=t;
|
|
T* ptr2=tab.t;
|
|
for (int i=0;i<taille;i++)
|
|
// copie des elements du tableau se trouvant a droite dans le tableau se trouvant
|
|
// a gauche du signe d'affectation
|
|
(*ptr1++)=(*ptr2++);
|
|
};
|
|
// et retour
|
|
return (*this);
|
|
};
|
|
// sinon on réajuste les tailles
|
|
if ( t!=NULL ) Libere(); // cas ou le tableau se trouvant a gauche du signe =
|
|
// n'est pas vide : desallocation de ce tableau
|
|
if ( tab.taille==0 )
|
|
// cas ou le tableau se trouvant a droite du signe = est vide : initialisation
|
|
// identique a l'appel du constructeur par defaut
|
|
{
|
|
taille=0;
|
|
t=NULL;
|
|
}
|
|
else
|
|
// autres cas
|
|
{
|
|
taille=tab.taille;
|
|
t=new T [taille];
|
|
T* ptr1=t;
|
|
T* ptr2=tab.t;
|
|
for (int i=0;i<taille;i++)
|
|
// copie des elements du tableau se trouvant a droite dans le tableau se trouvant
|
|
// a gauche du signe d'affectation
|
|
(*ptr1++)=(*ptr2++);
|
|
};
|
|
return (*this);
|
|
|
|
}
|
|
|
|
template <class T>
|
|
inline int Tableau<T>::operator ==(const Tableau<T> & tab) const
|
|
// Surcharge de l'operateur ==
|
|
// Renvoie 1 si les deux tableaux sont egaux
|
|
// Renvoie 0 sinon
|
|
{
|
|
|
|
if ( tab.taille!=taille )
|
|
return 0;
|
|
else
|
|
{
|
|
T* ptr1=t;
|
|
T* ptr2=tab.t;
|
|
for (int i=0;i<taille;i++)
|
|
{
|
|
if ( (*ptr2++)!=(*ptr1++) )
|
|
return 0;
|
|
};
|
|
return 1;
|
|
};
|
|
|
|
}
|
|
|
|
// opération de lecture sur un flot d'entrée
|
|
// les données sont le type puis la dimension puis les datas
|
|
template <class T>
|
|
inline istream & Tableau<T>::Entree(istream & entree)
|
|
{ // vérification du type
|
|
string type;
|
|
entree >> type;
|
|
if (type != "Tableau")
|
|
{Sortie (1);
|
|
return entree;
|
|
}
|
|
int dime; entree >> type >> dime;
|
|
if (dime != taille)
|
|
Change_taille(dime);
|
|
for (int i=0;i<taille;i++)
|
|
entree >> t[i];
|
|
return entree;
|
|
}
|
|
|
|
// opération de lecture sur un flot d'entrée sans redimentionnement
|
|
// les données sont le type puis la dimension puis les datas
|
|
// ici il n'y a pas redimentionnement du tableau si la taille est suffisente
|
|
template <class T>
|
|
inline istream & Tableau<T>::Entree_sans_redim(istream & entree)
|
|
{ // vérification du type
|
|
string type;
|
|
entree >> type;
|
|
if (type != "Tableau")
|
|
{Sortie (1);
|
|
return entree;
|
|
}
|
|
int dime; entree >> type >> dime;
|
|
if (dime > taille) // redimensionnement que si la taille est insuffisente
|
|
Change_taille(dime);
|
|
for (int i=0;i<taille;i++)
|
|
entree >> t[i];
|
|
return entree;
|
|
}
|
|
|
|
// lectures sur le flot si la taille du tableau est identique ou supérieure à celle lue
|
|
// retour d'un pointeur nulle
|
|
// sinon, si la taille lue est supérieure à la taille du tableau actuellement existant
|
|
// il y a création d'un nouveau tableau de même type avec la taille adéquate
|
|
// et retour d'un pointeur sur le nouveau tableau
|
|
template <class T>
|
|
inline Tableau<T> * Tableau<T>::New_en_lecture_si_taille_superieur_a_lire(istream& entree)
|
|
{ Tableau<T> * pt_tableau = NULL; // init au cas courant
|
|
// vérification du type
|
|
string type;
|
|
entree >> type;
|
|
if (type != "Tableau")
|
|
{Sortie (1);
|
|
return pt_tableau;
|
|
}
|
|
int dime; entree >> type >> dime;
|
|
if (dime > taille)
|
|
{ // on crée un nouveau tableau
|
|
pt_tableau = new Tableau<T>(dime);
|
|
for (int i=0;i<dime;i++)
|
|
entree >> pt_tableau->t[i];
|
|
}
|
|
else
|
|
{ // cas d'une dimension suffisante
|
|
for (int i=0;i<dime;i++)
|
|
entree >> t[i];
|
|
};
|
|
return pt_tableau;
|
|
}
|
|
|
|
// opération d'écriture non formatée
|
|
// les données sont le type la dimension puis les datas, chacun
|
|
// séparé par un espace
|
|
template <class T>
|
|
inline ostream & Tableau<T>::Sortir( ostream & sort) const
|
|
{ // tout d'abord un indicateur donnant le type
|
|
sort << "Tableau :taille= " << taille << " ";
|
|
for (int i=0;i<taille;i++)
|
|
sort << t[i] << " ";
|
|
sort << "\n";
|
|
return sort;
|
|
}
|
|
|
|
// opération d'écriture non formatée, idem précédent mais sans retour chariot à la fin
|
|
// les données sont le type la dimension puis les datas, chacun
|
|
// séparé par un espace
|
|
template <class T>
|
|
inline ostream & Tableau<T>::Sortir_sansRet( ostream & sort) const
|
|
{ // tout d'abord un indicateur donnant le type
|
|
sort << "Tableau :taille= " << taille << " ";
|
|
for (int i=0;i<taille;i++)
|
|
sort << t[i] << " ";
|
|
return sort;
|
|
}
|
|
|
|
// test si la valeur passée en argument apartient au tableau
|
|
// ramène 0 si n'appartient pas sinon ramène l'indice dans le tableau
|
|
// t(i) = t[i+1]
|
|
template <class T>
|
|
inline int Tableau<T>::Contient(const T& e) const
|
|
{ for (int i=0;i<taille;i++)
|
|
if (t[i] == e) {return (i+1);}
|
|
return 0;
|
|
}
|
|
|
|
|
|
// initialisation avec la valeur passée en argument
|
|
template <class T>
|
|
inline bool Tableau<T>::Inita(const T& e)
|
|
{ for (int i=0;i<taille;i++)
|
|
t[i] = e;
|
|
return true; // par défaut
|
|
};
|
|
|
|
//// affichage du premier élément pour les messages d'erreur
|
|
//template <class T>
|
|
//inline void Tableau<T>::Affiche_premier_elem( ostream & sort) const
|
|
// { // on indique quelque infos sup pour la compréhension
|
|
// sort << "Tableau :taille= " << taille << " ";
|
|
// if (taille >0)
|
|
// {sort << "\n le premier element du tableau pour info: ";
|
|
// sort << t[0] ;
|
|
// sort << endl;};
|
|
// }
|
|
|
|
|
|
//#include "ParaGlob.h"
|
|
|
|
#endif
|