// 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:        14/03/2003                                          *
 *                                                                $     *
 *     AUTEUR:      G RIO   (mailto:gerardrio56@free.fr)                *
 *                                                                $     *
 *     PROJET:      Herezh++                                            *
 *                                                                $     *
 ************************************************************************
 *     BUT:   conteneurs ultra basiques, permettant entre autres        *
 *            la différentiation des types.                             *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *                                                                $     *
 ************************************************************************/
#ifndef BASIQUES_H
#define BASIQUES_H

#include <iostream>
#include <fstream>
#include <string.h>
#include <string>
#include "Enum_IO_XML.h"
using namespace std;

#ifdef UTILISATION_MPI
  #include <boost/mpi.hpp>
  #include <boost/serialization/string.hpp>
  namespace mpi = boost::mpi;
#endif

/** @defgroup Les_conteneurs_ultra_basiques
*
*     BUT:   conteneurs ultra basiques, permettant entre autres        *
*            la différentiation des types.                             *
*
*
* \author    Gérard Rio
* \version   1.0
* \date       14/03/2003
* \brief       Listes des conteneurs ultra basiques
*
*/

/// @addtogroup Les_conteneurs_ultra_basiques
///  @{
///

/// cas de 2 entiers
class  DeuxEntiers
{
  public :
    // VARIABLES PUBLIQUES :
    int un,deux;
    // gestion schéma XML
    static short int impre_schem_XML;

  #ifdef UTILISATION_MPI
  private:
    friend class boost::serialization::access;
    // When the class Archive corresponds to an output archive, the
    // & operator is defined similar to <<.  Likewise, when the class Archive
    // is a type of input archive the & operator is defined similar to >>.
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    { ar & un; ar & deux; }
  #endif

  public :

    // CONSTRUCTEURS :
    DeuxEntiers() : un(0),deux(0) {};
    DeuxEntiers(int u, int v) : un(u),deux(v) {};
    DeuxEntiers(const DeuxEntiers & de) : un(de.un),deux(de.deux) {};
        
    // DESTRUCTEUR :
    ~DeuxEntiers() {};
    
    // METHODES PUBLIQUES :
    // surcharge de l'affectation 
    DeuxEntiers& operator= (const DeuxEntiers& de)
     { un = de.un; deux = de.deux; return (*this);};
    // surcharge de l'operator de lecture
    friend  istream & operator >> (istream & ent, DeuxEntiers & de)
     { ent >> de.un >> de.deux; return ent;};
    // surcharge de l'operator d'ecriture
    friend  ostream & operator << (ostream & sort , const DeuxEntiers & de)
     { sort << de.un <<" " << de.deux << " "; return sort;};
    // surcharge de lecture en XML
    istream & LectXML_DeuxEntiers(istream & ent);
    // surcharge d'ecriture en XML
    ostream & EcritXML_DeuxEntiers(ostream & sort);
    //Surcharge d'operateurs logiques
    bool operator == (const DeuxEntiers& a) const
    {  if (( un==a.un) && (deux==a.deux)) return true; else return false;};
    bool operator != (const DeuxEntiers& a) const { return !(*this == a);};
    // !*!*!*!  surchage de l'opérateur de comparaison : ici elle se fait uniquement
    // sur le deuxième entier !*!*!*! 
    bool operator > (const DeuxEntiers& a) const { return (this->deux > a.deux);};
    bool operator >= (const DeuxEntiers& a) const { return (this->deux >= a.deux);};
    bool operator < (const DeuxEntiers& a) const { return (this->deux < a.deux);};
    bool operator <= (const DeuxEntiers& a) const { return (this->deux <= a.deux);};
    // sortie du schemaXML: en fonction de enu
    void SchemaXML_DeuxEntiers(ostream& sort,const Enum_IO_XML enu) const ;
 };
/// @}  // end of group

/// @addtogroup Les_conteneurs_ultra_basiques
///  @{
///

/// cas de 2 double
class  DeuxDoubles
{
  public :
    // VARIABLES PUBLIQUES :
    double un,deux;
    // gestion schéma XML
    static short int impre_schem_XML;

    #ifdef UTILISATION_MPI
    private:
      friend class boost::serialization::access;
      // When the class Archive corresponds to an output archive, the
      // & operator is defined similar to <<.  Likewise, when the class Archive
      // is a type of input archive the & operator is defined similar to >>.
      template<class Archive>
      void serialize(Archive & ar, const unsigned int version)
      { ar & un; ar & deux; }
    #endif

    public :

    // CONSTRUCTEURS :
    DeuxDoubles() : un(0.),deux(0.) {};
    DeuxDoubles(double u, double v) : un(u),deux(v) {};
    DeuxDoubles(const DeuxDoubles & de) : un(de.un),deux(de.deux) {};
        
    // DESTRUCTEUR :
    ~DeuxDoubles() {};
    
    // METHODES PUBLIQUES :
    // surcharge de l'affectation 
    DeuxDoubles& operator= (const DeuxDoubles& de)
     { un = de.un; deux = de.deux; return (*this);};
    // surcharge de l'operator de lecture
    friend  istream & operator >> (istream & ent, DeuxDoubles & de)
     { ent >> de.un >> de.deux; return ent;};
    // surcharge de l'operator d'ecriture
    friend  ostream & operator << (ostream & sort , const DeuxDoubles & de)
     { sort << de.un <<" " << de.deux << " "; return sort;};
    // surcharge de lecture en XML
    istream & LectXML_DeuxDoubles(istream & ent);
    // surcharge d'ecriture en XML
    ostream & EcritXML_DeuxDoubles(ostream & sort);
    //Surcharge d'operateurs logiques
    bool operator == (const DeuxDoubles& a) const
    {  if (( un==a.un) && (deux==a.deux)) return true; else return false;};
    bool operator != ( const DeuxDoubles& a) const { return !(*this == a);};
    // sortie du schemaXML: en fonction de enu
    void SchemaXML_DeuxDoubles(ostream& sort,const Enum_IO_XML enu) const ;
 };
 /// @}  // end of group

/// @addtogroup Les_conteneurs_ultra_basiques
///  @{
///

/// cas d' 1 entier et 1 double
class  Entier_et_Double
{
  public :
    // VARIABLES PUBLIQUES :
    double x;
    int n;
    // gestion schéma XML
    static short int impre_schem_XML;

    #ifdef UTILISATION_MPI
    private:
      friend class boost::serialization::access;
      // When the class Archive corresponds to an output archive, the
      // & operator is defined similar to <<.  Likewise, when the class Archive
      // is a type of input archive the & operator is defined similar to >>.
      template<class Archive>
      void serialize(Archive & ar, const unsigned int version)
      { ar & x; ar & n; }
    #endif

    public :

    // CONSTRUCTEURS :
    Entier_et_Double() : x(0),n(0.) {};
    Entier_et_Double(int u, double v) : n(u),x(v) {};
    Entier_et_Double(const Entier_et_Double & de) : x(de.x),n(de.n) {};
        
    // DESTRUCTEUR :
    ~Entier_et_Double() {};
    
    // METHODES PUBLIQUES :
    // surcharge de l'affectation 
    Entier_et_Double& operator= (const Entier_et_Double& de)
     { x = de.x; n = de.n; return (*this);};
    // surcharge de l'operator de lecture
    friend  istream & operator >> (istream & ent, Entier_et_Double & de)
     { ent >> de.n >> de.x; return ent;};
    // surcharge de l'operator d'ecriture
    friend  ostream & operator << (ostream & sort , const Entier_et_Double & de)
     { sort << de.n <<" " << de.x << " "; return sort;};
    // surcharge de lecture en XML
    istream & LectXML_Entier_et_Double(istream & ent);
    // surcharge d'ecriture en XML
    ostream & EcritXML_Entier_et_Double(ostream & sort);
    //Surcharge d'operateurs logiques
    bool operator == (const Entier_et_Double& a) const
    {  if (( n==a.n) && (x==a.x)) return true; else return false;};
    bool operator != (const Entier_et_Double& a) const { return !(*this == a);};
    // sortie du schemaXML: en fonction de enu
    void SchemaXML_Entier_et_Double(ostream& sort,const Enum_IO_XML enu) const ;
    // surchage de l'opérateur de comparaison : ici elle se fait uniquement sur le double
    bool operator > (const Entier_et_Double& a) const { return (this->x > a.x);};
    bool operator >= (const Entier_et_Double& a) const { return (this->x >= a.x);};
    bool operator < (const Entier_et_Double& a) const { return (this->x < a.x);};
    bool operator <= (const Entier_et_Double& a) const { return (this->x <= a.x);};
 };
 /// @}  // end of group

/// @addtogroup Les_conteneurs_ultra_basiques
///  @{
///

/// cas de deux String
class  Deux_String
{
  public :
    // VARIABLES PUBLIQUES :
    string nom1,nom2;
    // gestion schéma XML
    static short int impre_schem_XML;

    #ifdef UTILISATION_MPI
    private:
      friend class boost::serialization::access;
      // When the class Archive corresponds to an output archive, the
      // & operator is defined similar to <<.  Likewise, when the class Archive
      // is a type of input archive the & operator is defined similar to >>.
      template<class Archive>
      void serialize(Archive & ar, const unsigned int version)
      { ar & nom1; ar & nom2; }
    #endif

    public :

    // CONSTRUCTEURS :
    Deux_String() : nom1(),nom2() {};
    Deux_String(const string& n1, const string& n2) : nom1(n1),nom2(n2) {};
    Deux_String(const Deux_String & de) : nom1(de.nom1),nom2(de.nom2) {};
        
    // DESTRUCTEUR :
    ~Deux_String() {};
    
    // METHODES PUBLIQUES :
    // surcharge de l'affectation 
    Deux_String& operator= (const Deux_String& de)
     { nom1 = de.nom1; nom2 = de.nom2; return (*this);};
    // surcharge de l'operator de lecture
    friend  istream & operator >> (istream & ent, Deux_String & de)
     { ent >> de.nom1 >> de.nom2; return ent;};
    // surcharge de l'operator d'ecriture
    friend  ostream & operator << (ostream & sort , const Deux_String & de)
     { sort << de.nom1 <<" " << de.nom2 << " "; return sort;};
    // surcharge de lecture en XML
    istream & LectXML_Deux_String(istream & ent);
    // surcharge d'ecriture en XML
    ostream & EcritXML_Deux_String(ostream & sort);
    //Surcharge d'operateurs logiques
    bool operator == (const Deux_String& a) const
    {  if (( nom1 == a.nom1) && (nom2 == a.nom2)) return true; else return false;};
    bool operator != (const Deux_String& a) const { return !(*this == a);};
    // sortie du schemaXML: en fonction de enu
    void SchemaXML_Deux_String(ostream& sort,const Enum_IO_XML enu) const ;
    // surchage de l'opérateur de comparaison : ici elle se fait uniquement sur le premier nom = nom1
    bool operator > (const Deux_String& a) const { return (this->nom1 > a.nom1);};
    bool operator >= (const Deux_String& a) const { return (this->nom1 >= a.nom1);};
    bool operator < (const Deux_String& a) const { return (this->nom1 < a.nom1);};
    bool operator <= (const Deux_String& a) const { return (this->nom1 <= a.nom1);};
 };
 /// @}  // end of group

/// @addtogroup Les_conteneurs_ultra_basiques
///  @{
///

/// cas d'un string et un entier
class  String_et_entier
{
  public :
    // VARIABLES PUBLIQUES :
    string nom;
    int n;
    // gestion schéma XML
    static short int impre_schem_XML;

    #ifdef UTILISATION_MPI
    private:
      friend class boost::serialization::access;
      // When the class Archive corresponds to an output archive, the
      // & operator is defined similar to <<.  Likewise, when the class Archive
      // is a type of input archive the & operator is defined similar to >>.
      template<class Archive>
      void serialize(Archive & ar, const unsigned int version)
      { ar & nom; ar & n; }
    #endif

    public :

    // CONSTRUCTEURS :
    String_et_entier() : nom(),n() {};
    String_et_entier(const string& nomm, int nn) : nom(nomm),n(nn) {};
    String_et_entier(const String_et_entier & de) : nom(de.nom),n(de.n) {};
        
    // DESTRUCTEUR :
    ~String_et_entier() {};
    
    // METHODES PUBLIQUES :
    // surcharge de l'affectation 
    String_et_entier& operator= (const String_et_entier& de)
     { nom = de.nom; n = de.n; return (*this);};
    // surcharge de l'operator de lecture
    friend  istream & operator >> (istream & ent, String_et_entier & de)
     { ent >> de.nom >> de.n; return ent;};
    // surcharge de l'operator d'ecriture
    friend  ostream & operator << (ostream & sort , const String_et_entier & de)
     { sort << de.nom <<" " << de.n << " "; return sort;};
    // surcharge de lecture en XML
    istream & LectXML_String_et_entier(istream & ent);
    // surcharge d'ecriture en XML
    ostream & EcritXML_String_et_entier(ostream & sort);
    //Surcharge d'operateurs logiques
    bool operator == (const  String_et_entier& a) const
    {  if (( nom == a.nom) && (n == a.n)) return true; else return false;};
    bool operator != (const String_et_entier& a) const { return !(*this == a);};
    // sortie du schemaXML: en fonction de enu
    void SchemaXML_String_et_entier(ostream& sort,const Enum_IO_XML enu) const ;
 };
 /// @}  // end of group

/// @addtogroup Les_conteneurs_ultra_basiques
///  @{
///

/// cas de trois String
class  Trois_String
{
  public :
    // VARIABLES PUBLIQUES :
    string nom1,nom2,nom3;
    // gestion schéma XML
    static short int impre_schem_XML;

    #ifdef UTILISATION_MPI
    private:
      friend class boost::serialization::access;
      // When the class Archive corresponds to an output archive, the
      // & operator is defined similar to <<.  Likewise, when the class Archive
      // is a type of input archive the & operator is defined similar to >>.
      template<class Archive>
      void serialize(Archive & ar, const unsigned int version)
      { ar & nom1; ar & nom2; ar & nom3;}
    #endif

    public :

    // CONSTRUCTEURS :
    Trois_String() : nom1(),nom2(),nom3() {};
    Trois_String(const string& n1, const string& n2,const string& n3) : nom1(n1),nom2(n2),nom3(n3) {};
    Trois_String(const Trois_String & de) : nom1(de.nom1),nom2(de.nom2),nom3(de.nom3) {};
        
    // DESTRUCTEUR :
    ~Trois_String() {};
    
    // METHODES PUBLIQUES :
    // surcharge de l'affectation 
    Trois_String& operator= (const Trois_String& de)
     { nom1 = de.nom1; nom2 = de.nom2; nom3 = de.nom3; return (*this);};
    // surcharge de l'operator de lecture
    friend  istream & operator >> (istream & ent, Trois_String & de)
     { ent >> de.nom1 >> de.nom2 >> de.nom3; return ent;};
    // surcharge de l'operator d'ecriture
    friend  ostream & operator << (ostream & sort , const Trois_String & de)
     { sort << de.nom1 <<" " << de.nom2 << " "<< de.nom3 << " "; return sort;};
    // surcharge de lecture en XML
    istream & LectXML_Trois_String(istream & ent);
    // surcharge d'ecriture en XML
    ostream & EcritXML_Trois_String(ostream & sort);
    //Surcharge d'operateurs logiques
    bool operator == (const Trois_String& a) const
    {  if (( nom1 == a.nom1) && (nom2 == a.nom2)&& (nom3 == a.nom3)) return true; else return false;};
    bool operator != (const Trois_String& a) const { return !(*this == a);};
    // sortie du schemaXML: en fonction de enu
    void SchemaXML_Trois_String(ostream& sort,const Enum_IO_XML enu) const ;
    // surchage de l'opérateur de comparaison : ici elle se fait uniquement sur le premier nom = nom1
    bool operator > (const Trois_String& a) const { return (this->nom1 > a.nom1);};
    bool operator >= (const Trois_String& a) const { return (this->nom1 >= a.nom1);};
    bool operator < (const Trois_String& a) const { return (this->nom1 < a.nom1);};
    bool operator <= (const Trois_String& a) const { return (this->nom1 <= a.nom1);};
 };
 /// @}  // end of group

/// @addtogroup Les_conteneurs_ultra_basiques
///  @{
///

/// cas de 4  string et un entier
class  Quatre_string_un_entier
{
  public :
    // VARIABLES PUBLIQUES :
    string nom1,nom2,nom3,nom4;
    int n;
    // gestion schéma XML
    static short int impre_schem_XML;

    #ifdef UTILISATION_MPI
    private:
      friend class boost::serialization::access;
      // When the class Archive corresponds to an output archive, the
      // & operator is defined similar to <<.  Likewise, when the class Archive
      // is a type of input archive the & operator is defined similar to >>.
      template<class Archive>
      void serialize(Archive & ar, const unsigned int version)
      { ar & nom1; ar & nom2; ar & nom3; ar & nom4; ar & n;}
    #endif

    public :

    // CONSTRUCTEURS :
    Quatre_string_un_entier() : nom1(""),nom2(""),nom3(""),nom4(""),n(0) {};
    Quatre_string_un_entier(const string& n1, const string& n2,const string& n3,const string& n4,const int& nn) : nom1(n1),nom2(n2),nom3(n3),nom4(n4),n(nn) {};
    Quatre_string_un_entier(const Quatre_string_un_entier & de) :
      nom1(de.nom1),nom2(de.nom2),nom3(de.nom3),nom4(de.nom4),n(de.n) {};
 
    // DESTRUCTEUR :
    ~Quatre_string_un_entier() {};
 
    // METHODES PUBLIQUES :
    // surcharge de l'affectation
    Quatre_string_un_entier& operator= (const Quatre_string_un_entier& de)
     { nom1 = de.nom1; nom2 = de.nom2; nom3 = de.nom3;nom4 = de.nom4;n=de.n;
      return (*this);};
    // surcharge de l'operator de lecture
    friend  istream & operator >> (istream & ent, Quatre_string_un_entier & de)
     { ent >> de.nom1 >> de.nom2 >> de.nom3>> de.nom4>> de.n; return ent;};
    // surcharge de l'operator d'ecriture
    friend  ostream & operator << (ostream & sort , const Quatre_string_un_entier & de)
     { sort << de.nom1 <<" " << de.nom2 << " "<< de.nom3 << " "<< de.nom4 << " "<< de.n << " "; return sort;};
    // surcharge de lecture en XML
    istream & LectXML_Quatre_string_un_entier(istream & ent);
    // surcharge d'ecriture en XML
    ostream & EcritXML_Quatre_string_un_entier(ostream & sort);
    //Surcharge d'operateurs logiques
    bool operator == (const Quatre_string_un_entier& a) const
    {  if (( nom1 == a.nom1) && (nom2 == a.nom2)&& (nom3 == a.nom3)&& (nom4 == a.nom4)&& (n == a.n))
        return true; else return false;};
    bool operator != (const Quatre_string_un_entier& a) const { return !(*this == a);};
    // sortie du schemaXML: en fonction de enu
    void SchemaXML_Quatre_string_un_entier(ostream& sort,const Enum_IO_XML enu) const ;
    // surchage de l'opérateur de comparaison : ici elle se fait par decroissance
    // est uniquement intéressante pour classer,
    bool operator > (const Quatre_string_un_entier& a) const
       { if (this->nom1 > a.nom1)
          {return true;}
         else if (this->nom1 < a.nom1)
          {return false;}
         else // cas d'une égalité
          // on passe au second string
          { if (this->nom2 > a.nom2)
              {return true;}
            else if (this->nom2 < a.nom2)
              {return false;}
            else // cas d'une égalité
             // on passe au troisième string
             { if (this->nom3 > a.nom3)
                 {return true;}
               else if (this->nom3 < a.nom3)
                 {return false;}
               else // cas d'une égalité
                 // on passe au quatrième string
                 { if (this->nom4 > a.nom4)
                     {return true;}
                   else if (this->nom4 < a.nom4)
                     {return false;}
                   else // cas d'une égalité
                     // on passe à l'entier
                     { if (this->n > a.n)
                         {return true;}
                       else if (this->n < a.n)
                         {return false;}
                       else // cas d'une égalité
                         {return false;}; // car totalement identique donc non supérieur
                     }
                  }
              }
          }
       };
    bool operator >= (const Quatre_string_un_entier& a) const
       { if (this->nom1 > a.nom1)
          {return true;}
         else if (this->nom1 < a.nom1)
          {return false;}
         else // cas d'une égalité
          // on passe au second string
          { if (this->nom2 > a.nom2)
              {return true;}
            else if (this->nom2 < a.nom2)
              {return false;}
            else // cas d'une égalité
             // on passe au troisième string
             { if (this->nom3 > a.nom3)
                 {return true;}
               else if (this->nom3 < a.nom3)
                 {return false;}
               else // cas d'une égalité
                 // on passe au quatrième string
                 { if (this->nom4 > a.nom4)
                     {return true;}
                   else if (this->nom4 < a.nom4)
                     {return false;}
                   else // cas d'une égalité
                     // on passe à l'entier
                     { if (this->n > a.n)
                         {return true;}
                       else if (this->n < a.n)
                         {return false;}
                       else // cas d'une égalité
                         {return true;}; // car totalement identique
                     }
                  }
              }
          }
       };
 
    bool operator < (const Quatre_string_un_entier& a) const
       { if (this->nom1 < a.nom1)
          {return true;}
         else if (this->nom1 > a.nom1)
          {return false;}
         else // cas d'une égalité
          // on passe au second string
          { if (this->nom2 < a.nom2)
              {return true;}
            else if (this->nom2 > a.nom2)
              {return false;}
            else // cas d'une égalité
             // on passe au troisième string
             { if (this->nom3 < a.nom3)
                 {return true;}
               else if (this->nom3 > a.nom3)
                 {return false;}
               else // cas d'une égalité
                 // on passe au quatrième string
                 { if (this->nom4 < a.nom4)
                     {return true;}
                   else if (this->nom4 > a.nom4)
                     {return false;}
                   else // cas d'une égalité
                     // on passe à l'entier
                     { if (this->n < a.n)
                         {return true;}
                       else if (this->n > a.n)
                         {return false;}
                       else // cas d'une égalité
                         {return false;}; // car totalement identique donc non inférieur
                     }
                  }
              }
          }
       };
  
    bool operator <= (const Quatre_string_un_entier& a) const
           { if (this->nom1 < a.nom1)
          {return true;}
         else if (this->nom1 > a.nom1)
          {return false;}
         else // cas d'une égalité
          // on passe au second string
          { if (this->nom2 < a.nom2)
              {return true;}
            else if (this->nom2 > a.nom2)
              {return false;}
            else // cas d'une égalité
             // on passe au troisième string
             { if (this->nom3 < a.nom3)
                 {return true;}
               else if (this->nom3 > a.nom3)
                 {return false;}
               else // cas d'une égalité
                 // on passe au quatrième string
                 { if (this->nom4 < a.nom4)
                     {return true;}
                   else if (this->nom4 > a.nom4)
                     {return false;}
                   else // cas d'une égalité
                     // on passe à l'entier
                     { if (this->n < a.n)
                         {return true;}
                       else if (this->n > a.n)
                         {return false;}
                       else // cas d'une égalité
                         {return true;}; // car totalement identique
                     }
                  }
              }
          }
       };

 };
/// @}  // end of group

/// @addtogroup Les_conteneurs_ultra_basiques
///  @{
///

/// cas de 3 entiers
class  TroisEntiers
{
  public :
    // VARIABLES PUBLIQUES :
    int un,deux,trois;
    // gestion schéma XML
    static short int impre_schem_XML;

    #ifdef UTILISATION_MPI
    private:
      friend class boost::serialization::access;
      // When the class Archive corresponds to an output archive, the
      // & operator is defined similar to <<.  Likewise, when the class Archive
      // is a type of input archive the & operator is defined similar to >>.
      template<class Archive>
      void serialize(Archive & ar, const unsigned int version)
      { ar & un; ar & deux; ar & trois;}
    #endif

    public :

    // CONSTRUCTEURS :
    TroisEntiers() : un(0),deux(0),trois(0) {};
    TroisEntiers(int u, int v,int w) : un(u),deux(v),trois(w) {};
    TroisEntiers(const TroisEntiers & de) : un(de.un),deux(de.deux),trois(de.trois) {};
 
    // DESTRUCTEUR :
    ~TroisEntiers() {};
 
    // METHODES PUBLIQUES :
    // surcharge de l'affectation
    TroisEntiers& operator= (const TroisEntiers& de)
     { un = de.un; deux = de.deux;trois = de.trois; return (*this);};
    // surcharge de l'operator de lecture
    friend  istream & operator >> (istream & ent, TroisEntiers & de)
     { ent >> de.un >> de.deux >> de.trois; return ent;};
    // surcharge de l'operator d'ecriture
    friend  ostream & operator << (ostream & sort , const TroisEntiers & de)
     { sort << de.un <<" " << de.deux << " "<< de.trois<< " "; return sort;};
    // surcharge de lecture en XML
    istream & LectXML_TroisEntiers(istream & ent);
    // surcharge d'ecriture en XML
    ostream & EcritXML_TroisEntiers(ostream & sort);
    //Surcharge d'operateurs logiques
    bool operator == (const TroisEntiers& a) const
    {  if (( un==a.un) && (deux==a.deux) && (trois == a.trois)) return true; else return false;};
    bool operator != (const TroisEntiers& a) const { return !(*this == a);};
    //  surchage de l'opérateur de comparaison
    bool operator > (const TroisEntiers& a) const
      { if (un > a.un)
          {return true;}
        else if (un < a.un)
          {return false;}
        else // egalité, on test le suivant
          {if (deux > a.deux)
            {return true;}
           else if (deux < a.deux)
            {return false;}
           else // egalité, on test le suivant
            {if (trois > a.trois)
              {return true;}
             else if (trois < a.trois)
              {return false;}
             else // egalité, on test le suivant
              {return false;} // car c'est l'égalité parfaite donc pas supérieur
            }
          }
      };
    bool operator >= (const TroisEntiers& a) const
      { if (un > a.un)
          {return true;}
        else if (un < a.un)
          {return false;}
        else // egalité, on test le suivant
          {if (deux > a.deux)
            {return true;}
           else if (deux < a.deux)
            {return false;}
           else // egalité, on test le suivant
            {if (trois > a.trois)
              {return true;}
             else if (trois < a.trois)
              {return false;}
             else // egalité, on test le suivant
              {return true;} // car c'est l'égalité parfaite
            }
          }
      };
    bool operator < (const TroisEntiers& a) const
      { if (un < a.un)
          {return true;}
        else if (un > a.un)
          {return false;}
        else // egalité, on test le suivant
          {if (deux < a.deux)
            {return true;}
           else if (deux > a.deux)
            {return false;}
           else // egalité, on test le suivant
            {if (trois < a.trois)
              {return true;}
             else if (trois > a.trois)
              {return false;}
             else // egalité, on test le suivant
              {return false;} // car c'est l'égalité parfaite donc pas inférieur
            }
          }
      };
    bool operator <= (const TroisEntiers& a) const
      { if (un < a.un)
          {return true;}
        else if (un > a.un)
          {return false;}
        else // egalité, on test le suivant
          {if (deux < a.deux)
            {return true;}
           else if (deux > a.deux)
            {return false;}
           else // egalité, on test le suivant
            {if (trois < a.trois)
              {return true;}
             else if (trois > a.trois)
              {return false;}
             else // egalité, on test le suivant
              {return true;} // car c'est l'égalité parfaite
            }
          }
      };
    // sortie du schemaXML: en fonction de enu
    void SchemaXML_TroisEntiers(ostream& sort,const Enum_IO_XML enu) const ;
 };
/// @}  // end of group

/// @addtogroup Les_conteneurs_ultra_basiques
///  @{
///

/// cas de deux String et un entier
class  Deux_String_un_entier
{
 public :
   // VARIABLES PUBLIQUES :
   string nom1,nom2;
   int n;
   // gestion schéma XML
   static short int impre_schem_XML;

   #ifdef UTILISATION_MPI
   private:
     friend class boost::serialization::access;
     // When the class Archive corresponds to an output archive, the
     // & operator is defined similar to <<.  Likewise, when the class Archive
     // is a type of input archive the & operator is defined similar to >>.
     template<class Archive>
     void serialize(Archive & ar, const unsigned int version)
     { ar & nom1; ar & nom2; ar & n;}
   #endif

   public :

   // CONSTRUCTEURS :
   Deux_String_un_entier() : nom1(""),nom2(""),n(0) {};
   Deux_String_un_entier(const string& n1, const string& n2,const int& nn)
       : nom1(n1),nom2(n2),n(nn) {};
   Deux_String_un_entier(const Deux_String_un_entier & de) :
     nom1(de.nom1),nom2(de.nom2),n(de.n) {};

   // DESTRUCTEUR :
   ~Deux_String_un_entier() {};

   // METHODES PUBLIQUES :
   // surcharge de l'affectation
   Deux_String_un_entier& operator= (const Deux_String_un_entier& de)
    { nom1 = de.nom1; nom2 = de.nom2; n=de.n;
     return (*this);};
   // surcharge de l'operator de lecture
   friend  istream & operator >> (istream & ent, Deux_String_un_entier & de)
    { ent >> de.nom1 >> de.nom2 >>  de.n; return ent;};
   // surcharge de l'operator d'ecriture
   friend  ostream & operator << (ostream & sort , const Deux_String_un_entier & de)
    { sort << de.nom1 <<" " << de.nom2  << " "<< de.n << " "; return sort;};
   // surcharge de lecture en XML
   istream & LectXML_Deux_String_un_entier(istream & ent);
   // surcharge d'ecriture en XML
   ostream & EcritXML_Deux_String_un_entier(ostream & sort);
   //Surcharge d'operateurs logiques
   bool operator == (const Deux_String_un_entier& a) const
   {  if (( nom1 == a.nom1) && (nom2 == a.nom2)&& (n == a.n))
       return true; else return false;};
   bool operator != (const Deux_String_un_entier& a) const { return !(*this == a);};
   // sortie du schemaXML: en fonction de enu
   void SchemaXML_Deux_String_un_entier(ostream& sort,const Enum_IO_XML enu) const ;
   // surchage de l'opérateur de comparaison : ici elle se fait par decroissance
   // est uniquement intéressante pour classer,
   bool operator > (const Deux_String_un_entier& a) const
      { if (this->nom1 > a.nom1)
         {return true;}
        else if (this->nom1 < a.nom1)
         {return false;}
        else // cas d'une égalité
         // on passe au second string
         { if (this->nom2 > a.nom2)
             {return true;}
           else if (this->nom2 < a.nom2)
             {return false;}
           else // cas d'une égalité
             // on passe à l'entier
             { if (this->n > a.n)
                 {return true;}
               else if (this->n < a.n)
                 {return false;}
               else // cas d'une égalité
                 {return false;}; // car totalement identique donc non supérieur
             }
         }
      };
   bool operator >= (const Deux_String_un_entier& a) const
      { if (this->nom1 > a.nom1)
         {return true;}
        else if (this->nom1 < a.nom1)
         {return false;}
        else // cas d'une égalité
         // on passe au second string
         { if (this->nom2 > a.nom2)
             {return true;}
           else if (this->nom2 < a.nom2)
             {return false;}
           else // cas d'une égalité
             // on passe à l'entier
             { if (this->n > a.n)
                 {return true;}
               else if (this->n < a.n)
                 {return false;}
               else // cas d'une égalité
                 {return true;}; // car totalement identique
             }
         }
      };

   bool operator < (const Deux_String_un_entier& a) const
      { if (this->nom1 < a.nom1)
         {return true;}
        else if (this->nom1 > a.nom1)
         {return false;}
        else // cas d'une égalité
         // on passe au second string
         { if (this->nom2 < a.nom2)
             {return true;}
           else if (this->nom2 > a.nom2)
             {return false;}
           else // cas d'une égalité
             // on passe à l'entier
             { if (this->n < a.n)
                 {return true;}
               else if (this->n > a.n)
                 {return false;}
               else // cas d'une égalité
                 {return false;}; // car totalement identique donc non inférieur
             }
         }
      };
 
   bool operator <= (const Deux_String_un_entier& a) const
          { if (this->nom1 < a.nom1)
         {return true;}
        else if (this->nom1 > a.nom1)
         {return false;}
        else // cas d'une égalité
         // on passe au second string
         { if (this->nom2 < a.nom2)
             {return true;}
           else if (this->nom2 > a.nom2)
             {return false;}
           else // cas d'une égalité
             // on passe à l'entier
             { if (this->n < a.n)
                 {return true;}
               else if (this->n > a.n)
                 {return false;}
               else // cas d'une égalité
                 {return true;}; // car totalement identique
             }
         }
      };

};
/// @}  // end of group

/// @addtogroup Les_conteneurs_ultra_basiques
///  @{
///

/// cas de 4 entiers
class  QuatreEntiers
{
  public :
    // VARIABLES PUBLIQUES :
    int un,deux,trois,quatre;
    // gestion schéma XML
    static short int impre_schem_XML;

    #ifdef UTILISATION_MPI
    private:
      friend class boost::serialization::access;
      // When the class Archive corresponds to an output archive, the
      // & operator is defined similar to <<.  Likewise, when the class Archive
      // is a type of input archive the & operator is defined similar to >>.
      template<class Archive>
      void serialize(Archive & ar, const unsigned int version)
      { ar & un; ar & deux; ar & trois; ar & quatre;}
    #endif

    public :

    // CONSTRUCTEURS :
    QuatreEntiers() : un(0),deux(0),trois(0),quatre(0) {};
    QuatreEntiers(int u, int v,int w,int ww) : un(u),deux(v),trois(w),quatre(ww) {};
    QuatreEntiers(const QuatreEntiers & de) : un(de.un),deux(de.deux),trois(de.trois),quatre(de.quatre) {};
 
    // DESTRUCTEUR :
    ~QuatreEntiers() {};
 
    // METHODES PUBLIQUES :
    // surcharge de l'affectation
    QuatreEntiers& operator= (const QuatreEntiers& de)
     { un = de.un; deux = de.deux;trois = de.trois; quatre = de.quatre; return (*this);};
    // surcharge de l'operator de lecture
    friend  istream & operator >> (istream & ent, QuatreEntiers & de)
     { ent >> de.un >> de.deux >> de.trois >>  de.quatre; return ent;};
    // surcharge de l'operator d'ecriture
    friend  ostream & operator << (ostream & sort , const QuatreEntiers & de)
     { sort << de.un <<" " << de.deux << " "<< de.trois<< " "<<de.quatre << " "; return sort;};
    // surcharge de lecture en XML
    istream & LectXML_QuatreEntiers(istream & ent);
    // surcharge d'ecriture en XML
    ostream & EcritXML_QuatreEntiers(ostream & sort);
    //Surcharge d'operateurs logiques
    bool operator == (const QuatreEntiers& a) const
    {  if (( un==a.un) && (deux==a.deux) && (trois == a.trois)&& (quatre == a.quatre)) return true; else return false;};
    bool operator != (const QuatreEntiers& a) const { return !(*this == a);};
    //  surchage de l'opérateur de comparaison
    bool operator > (const QuatreEntiers& a) const
      { if (un > a.un)
          {return true;}
        else if (un < a.un)
          {return false;}
        else // egalité, on test le suivant
          {if (deux > a.deux)
            {return true;}
           else if (deux < a.deux)
            {return false;}
           else // egalité, on test le suivant
            {if (trois > a.trois)
              {return true;}
             else if (trois < a.trois)
              {return false;}
             else // egalité, on test le suivant
              {if (quatre > a.quatre)
                {return true;}
               else if (quatre < a.quatre)
                {return false;}
               else // egalité, on test le suivant
                {return false;} // car c'est l'égalité parfaite donc pas supérieur
              }
            }
          }
      };
    bool operator >= (const QuatreEntiers& a) const
      { if (un > a.un)
          {return true;}
        else if (un < a.un)
          {return false;}
        else // egalité, on test le suivant
          {if (deux > a.deux)
            {return true;}
           else if (deux < a.deux)
            {return false;}
           else // egalité, on test le suivant
            {if (trois > a.trois)
              {return true;}
             else if (trois < a.trois)
              {return false;}
             else // egalité, on test le suivant
              {if (quatre > a.quatre)
                {return true;}
               else if (quatre < a.quatre)
                {return false;}
               else // egalité, on test le suivant
                {return true;} // car c'est l'égalité parfaite
              }
            }
          }
      };
    bool operator < (const QuatreEntiers& a) const
      { if (un < a.un)
          {return true;}
        else if (un > a.un)
          {return false;}
        else // egalité, on test le suivant
          {if (deux < a.deux)
            {return true;}
           else if (deux > a.deux)
            {return false;}
           else // egalité, on test le suivant
            {if (trois < a.trois)
              {return true;}
             else if (trois > a.trois)
              {return false;}
             else // egalité, on test le suivant
              {if (quatre < a.quatre)
                {return true;}
               else if (quatre > a.quatre)
                {return false;}
               else // egalité, on test le suivant
                {return false;} // car c'est l'égalité parfaite donc pas inférieur
              }
            }
          }
      };
    bool operator <= (const QuatreEntiers& a) const
      { if (un < a.un)
          {return true;}
        else if (un > a.un)
          {return false;}
        else // egalité, on test le suivant
          {if (deux < a.deux)
            {return true;}
           else if (deux > a.deux)
            {return false;}
           else // egalité, on test le suivant
            {if (trois < a.trois)
              {return true;}
             else if (trois > a.trois)
              {return false;}
             else // egalité, on test le suivant
              {if (quatre < a.quatre)
                {return true;}
               else if (quatre > a.quatre)
                {return false;}
               else // egalité, on test le suivant
                {return true;} // car c'est l'égalité parfaite
              }
            }
          }
      };
    // sortie du schemaXML: en fonction de enu
    void SchemaXML_QuatreEntiers(ostream& sort,const Enum_IO_XML enu) const ;
 };
/// @}  // end of group

/// @addtogroup Les_conteneurs_ultra_basiques
///  @{
///

/// cas de 5 entiers
class  CinqEntiers
{
  public :
    // VARIABLES PUBLIQUES :
    int un,deux,trois,quatre,cinq;
    // gestion schéma XML
    static short int impre_schem_XML;

    #ifdef UTILISATION_MPI
    private:
      friend class boost::serialization::access;
      // When the class Archive corresponds to an output archive, the
      // & operator is defined similar to <<.  Likewise, when the class Archive
      // is a type of input archive the & operator is defined similar to >>.
      template<class Archive>
      void serialize(Archive & ar, const unsigned int version)
      { ar & un; ar & deux; ar & trois; ar & quatre; ar & cinq;}
    #endif

    public :

    // CONSTRUCTEURS :
    CinqEntiers() : un(0),deux(0),trois(0),quatre(0),cinq(0) {};
    CinqEntiers(int u, int v,int w1,int w2,int w3) : un(u),deux(v),trois(w1),quatre(w2),cinq(w3) {};
    CinqEntiers(const CinqEntiers & de) : un(de.un),deux(de.deux),trois(de.trois),quatre(de.quatre)
                   ,cinq(de.cinq) {};
 
    // DESTRUCTEUR :
    ~CinqEntiers() {};
 
    // METHODES PUBLIQUES :
    // surcharge de l'affectation
    CinqEntiers& operator= (const CinqEntiers& de)
     { un = de.un; deux = de.deux;trois = de.trois; quatre = de.quatre;
       cinq = de.cinq; return (*this);};
    // surcharge de l'operator de lecture
    friend  istream & operator >> (istream & ent, CinqEntiers & de)
     { ent >> de.un >> de.deux >> de.trois >>  de.quatre >> de.cinq; return ent;};
    // surcharge de l'operator d'ecriture
    friend  ostream & operator << (ostream & sort , const CinqEntiers & de)
     { sort << de.un <<" " << de.deux << " "<< de.trois<< " "<<de.quatre << " "
            << de.cinq << " "; return sort;};
    // surcharge de lecture en XML
    istream & LectXML_CinqEntiers(istream & ent);
    // surcharge d'ecriture en XML
    ostream & EcritXML_CinqEntiers(ostream & sort);
    //Surcharge d'operateurs logiques
    bool operator == (const CinqEntiers& a) const
    {  if (( un==a.un) && (deux==a.deux) && (trois == a.trois)&& (quatre == a.quatre)
           && (cinq == a.cinq) ) return true; else return false;};
    bool operator != (const CinqEntiers& a) const { return !(*this == a);};
    //  surchage de l'opérateur de comparaison
    bool operator > (const CinqEntiers& a) const
      { if (un > a.un)
          {return true;}
        else if (un < a.un)
          {return false;}
        else // egalité, on test le suivant
          {if (deux > a.deux)
            {return true;}
           else if (deux < a.deux)
            {return false;}
           else // egalité, on test le suivant
            {if (trois > a.trois)
              {return true;}
             else if (trois < a.trois)
              {return false;}
             else // egalité, on test le suivant
              {if (quatre > a.quatre)
                {return true;}
               else if (quatre < a.quatre)
                {return false;}
               else // egalité, on test le suivant
                {if (cinq > a.cinq)
                  {return true;}
                 else if (cinq < a.cinq)
                  {return false;}
                 else // egalité, on test le suivant
                  {return false;} // car c'est l'égalité parfaite donc pas supérieur
                }
              }
            }
          }
      };
    bool operator >= (const CinqEntiers& a) const
      { if (un > a.un)
          {return true;}
        else if (un < a.un)
          {return false;}
        else // egalité, on test le suivant
          {if (deux > a.deux)
            {return true;}
           else if (deux < a.deux)
            {return false;}
           else // egalité, on test le suivant
            {if (trois > a.trois)
              {return true;}
             else if (trois < a.trois)
              {return false;}
             else // egalité, on test le suivant
              {if (quatre > a.quatre)
                {return true;}
               else if (quatre < a.quatre)
                {return false;}
               else // egalité, on test le suivant
                {if (cinq > a.cinq)
                  {return true;}
                 else if (cinq < a.cinq)
                  {return false;}
                 else // egalité, on test le suivant
                  {return true;} // car c'est l'égalité parfaite
                }
              }
            }
          }
      };
    bool operator < (const CinqEntiers& a) const
      { if (un < a.un)
          {return true;}
        else if (un > a.un)
          {return false;}
        else // egalité, on test le suivant
          {if (deux < a.deux)
            {return true;}
           else if (deux > a.deux)
            {return false;}
           else // egalité, on test le suivant
            {if (trois < a.trois)
              {return true;}
             else if (trois > a.trois)
              {return false;}
             else // egalité, on test le suivant
              {if (quatre < a.quatre)
                {return true;}
               else if (quatre > a.quatre)
                {return false;}
               else // egalité, on test le suivant
                {if (cinq < a.cinq)
                  {return true;}
                 else if (cinq > a.cinq)
                  {return false;}
                 else // egalité, on test le suivant
                  {return false;} // car c'est l'égalité parfaite donc pas inférieur
                }
              }
            }
          }
      };
    bool operator <= (const CinqEntiers& a) const
      { if (un < a.un)
          {return true;}
        else if (un > a.un)
          {return false;}
        else // egalité, on test le suivant
          {if (deux < a.deux)
            {return true;}
           else if (deux > a.deux)
            {return false;}
           else // egalité, on test le suivant
            {if (trois < a.trois)
              {return true;}
             else if (trois > a.trois)
              {return false;}
             else // egalité, on test le suivant
              {if (quatre < a.quatre)
                {return true;}
               else if (quatre > a.quatre)
                {return false;}
               else // egalité, on test le suivant
                {if (cinq < a.cinq)
                  {return true;}
                 else if (cinq > a.cinq)
                  {return false;}
                 else // egalité, on test le suivant
                  {return true;} // car c'est l'égalité parfaite
                }
              }
            }
          }
      };
    // sortie du schemaXML: en fonction de enu
    void SchemaXML_CinqEntiers(ostream& sort,const Enum_IO_XML enu) const ;
 };
/// @}  // end of group

#endif