1 #ifndef __TABLEAU__
   2 #define __TABLEAU__
   3 
   4 #include <cstdlib>
   5 #include <iostream>
   6 using namespace std;
   7 
   8 // Un objet-fonction general, a un parametre
   9 template <typename T=float> class Functor1p {
  10 public:
  11     virtual T operator()(T) const = 0;
  12 };
  13 
  14 template <typename T=float, size_t S=100> class Tableau {
  15 public:
  16 
  17         // Le constructeur principal
  18         explicit Tableau();
  19 
  20         // Le trio infernal
  21         Tableau (const Tableau & );
  22         Tableau & operator=(const Tableau &);
  23         ~Tableau();
  24 
  25         // renvoie la taille du Tableau
  26         size_t size() const { return S;};
  27         
  28         // renvoie un element du Tableau sans deborder
  29         T & operator[](size_t i);
  30         
  31         // meme chose - version const
  32         T operator[](size_t i) const;
  33         
  34         // operateurs +=
  35         // Le parametre est un autre Tableau
  36         Tableau & operator+=(const Tableau & );
  37         
  38         // Le parametre est un T
  39         Tableau & operator+=(T );
  40         
  41         // imprime le Tableau sur la sortie standard
  42         void print () const;
  43         
  44         // La fonction transform: on leur passe un objet-fonction à 1 paramètre
  45         void transform(const Functor1p<T>& );
  46 
  47 private:
  48         T A[S];
  49         
  50         // Le signe __ rappelle qu'il s'agit de methodes privees
  51         void __copie (T src, T dest[]);
  52         void __copie (T src[], T dest[]);
  53 };
  54 
  55 // Une fonction qui n'est pas une methode
  56 template < typename T,size_t S> Tableau<T, S> operator+(const Tableau<T, S>& t1, const Tableau<T, S>& t2);
  57 
  58 // Le constructeur principal - pas d'allocation memoire a faire !
  59 template <typename T,size_t S> Tableau<T, S>::Tableau() {
  60         cerr << "constructeur sz = " <<  S << '\n';
  61         __copie(0.0,A);
  62 };
  63 
  64 // CE QUI  SUIT ETAIT JU SQUE LA DAN S LE .cpp
  65 
  66 // Le constructeur de copie - pas d'allocation memoire a faire !
  67 template <typename T,size_t S> Tableau<T, S>::Tableau (const Tableau<T, S> & t) {
  68         cerr << "constructeur de copie" << '\n';
  69         __copie(t.A,A);
  70 };
  71 
  72 // L'operateur = PA S D'ALLOCATION DE MEMOIRE, juste gerer les identites
  73 template <typename T, size_t S> Tableau<T, S> & Tableau<T, S>::operator=(const Tableau<T, S> &t) {
  74         cerr << "operateur =" << '\n';
  75         if (this==&t)    // Pour gerer les cas A=A
  76                 return *this;
  77         __copie(t.A,A);
  78         return *this;
  79 };
  80 
  81 // Le destructeur: PA S NECE S SAIRE ICI
  82 template <typename T, size_t S> Tableau<T,S>::~Tableau() { 
  83         cerr << "destructeur (sz = " << S << ")\n";
  84 };
  85 
  86 // renvoie un element du tableau sans deborder
  87 // pas la peine de tester i < 0, size_t est un type unsigned
  88 // (decommentez ce qui suit vous verrez si cela compile)
  89 template <typename T,size_t S> T & Tableau<T, S>::operator[](size_t i) {
  90         //if (i<0) {
  91         //  cerr << "ATTENTION Debordement de tableau - je renvoie tableau[0]\n";
  92         //  return *A;
  93         //} else
  94         if (i>= S) {
  95                 cerr << "ATTENTION Debordement de Tableau - je renvoie Tableau[sz-1]\n";
  96                 return A[S-1];
  97                 // return *(A+sz-1);  // Une autre manière d'écrire la même chose
  98         } else {
  99                 return A[i];
 100                 //return *(A+i);
 101         };
 102 };
 103 
 104 // meme chose - version const
 105 template <typename T, size_t S> T Tableau<T, S>::operator[](size_t i) const {
 106         if (i>= S) {
 107                 cerr << "ATTENTION Debordement de Tableau - je renvoie Tableau[sz-1]\n";
 108                 return A[S-1];
 109         } else {
 110                 return A[i];
 111         };
 112 };
 113 
 114 // operateurs +=
 115 // Le parametre est un autre Tableau
 116 template <typename T,size_t S> Tableau<T, S> & Tableau<T, S>::operator+=(const Tableau<T, S> & t) {
 117         for (size_t i=0; i <  S; i++) {
 118                 A[i] += t[i];
 119         };
 120         return *this;
 121 };
 122 
 123 // Le parametre est un T
 124 template <typename T,size_t S> Tableau<T, S> & Tableau<T, S>::operator+=(T x) {
 125         for (size_t i=0; i <  S; i++) {
 126                 A[i] += x;
 127         };
 128         return *this;
 129 };
 130 
 131 // imprime le Tableau sur la sortie standard
 132 template <typename T,size_t S> void Tableau<T, S>::print () const  {
 133         for (size_t i=0; i < S; i++) {
 134                 cout << A[i] << " ";
 135         };
 136         cout << '\n';
 137 }
 138 
 139 // copie l'entier src dans la zone memoire pointee par dest
 140 template <typename T,size_t S> void Tableau<T, S>::__copie (T src, T dest[])
 141 {
 142         for ( size_t i=0; i< S; i++) {
 143                 dest[i] = src;
 144         }
 145 }
 146 template <typename T,size_t S> void Tableau<T, S>::__copie (T src[], T dest[]) {
 147         for (size_t i=0; i< S; i++) {
 148                 dest[i] = src[i];
 149         };
 150 }
 151 
 152 // La famille de fonction transform: on lui passe un objet-fonction derive de Functor1p
 153 template <typename T,size_t S> void Tableau<T, S>::transform(const Functor1p<T>& f ) {
 154         for (int i=0; i<  S; i++) 
 155                 A[i]=f(A[i]);
 156 };
 157 
 158 template <typename T,size_t S> Tableau<T, S> operator+(const Tableau<T, S>& t1, const Tableau<T, S>& t2) {
 159         Tableau<T,S> s;
 160         s = t1;
 161         s += t2;
 162         return s;
 163 };
 164 
 165 #endif