1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
   | // Template class Dyn2DMatrix 
// 
// * la construction de cette matrice se fait de manière à ce que chaque rangée (row) comporte 
// le même nombre de colonnes (col). 
// * le type contenu dans le tableau doit avoir:
// -> un constructeur par défaut, 
// -> un constructeur de copie, 
// -> un opérateur d'affectation. 
// * il est possible de définir un élément neutre (neutralElement) dans le constructeur, cet 
// élément sert à remplir les trous du tableau. S'il n'est pas défini, l'élément neutre est 
// construit à partir du constructeur par défaut du type contenu dans le tableau. 
// * lorsqu'un élément est rajouté, la matrice s'aggrandit automatiquement ( voir mutateur )   
 
#ifndef DYN_2D_MATRIX 
#define DYN_2D_MATRIX   
 
#include <vector>   
 
namespace DynMatrix 
{   
 
template <typename T> 
class Dyn2DMatrix 
{ 
private: 
     size_t m_nbRow, m_nbCol; 
     std::vector<T> m_array; 
     T m_neutralElement;   
 
public: 
     // --- construction/destruction  
     Dyn2DMatrix()  
     : m_nbRow(0)
     , m_nbCol(0)
     , m_neutralElement(T())  
     { }
 
     Dyn2DMatrix(const size_t nbRow, const size_t nbCol)  
     : m_nbRow(nbRow)
     , m_nbCol(nbCol)
     , m_neutralElement(T())  
     {  
          std::vector<T>::iterator it = m_array.begin(); 
          m_array.insert(it, nbRow*nbCol, m_neutralElement); 
     }   
 
     Dyn2DMatrix(const T &neutralElement)  
     : m_nbRow(0)
     , m_nbCol(0), m_neutralElement(T())  
     { }   
 
     Dyn2DMatrix(const size_t nbRow, const size_t nbCol, const T &neutralElement)  
     : m_nbRow(nbRow)
     , m_nbCol(nbCol)
     , m_neutralElement(neutralElement)  
     {  
          std::vector<T>::iterator it = m_array.begin(); 
          m_array.insert(it, nbRow*nbCol, m_neutralElement); 
     }  
 
     ~Dyn2DMatrix(){}   
 
     // --- accesseurs  
     T operator() (const size_t row, const size_t col) const  
     {  
          if ( ( m_nbRow <= row ) || ( m_nbCol <= col ) )  
               throw std::exception("const Dyn2DMatrix subscript out of bounds");   
 
          return m_array[m_nbCol*row+col]; 
     }   
 
     size_t width() {return m_nbCol;}  
     size_t height() {return m_nbRow;}   
 
     // --- mutateurs  
     T &operator() (const size_t row, const size_t col)  
     {  
          // Dans un premier temps, je vérifie si la matrice est assez grande.  
          // Si elle ne l'est pas, je l'aggrandis.   
          if ( m_nbCol <= col )  
          {
               // je dois ajouter des colonnes  
               size_t colDiff = col - m_nbCol + 1; 
               for (size_t curRow = 0 ; curRow < m_nbRow ; ++curRow )  
               {  
                    std::vector<T>::iterator it = m_array.begin(); 
                    size_t tmp = curRow*(col+1) + m_nbCol; 
                    m_array.insert( it + tmp, colDiff, m_neutralElement); 
               }  
               m_nbCol = col+1; 
          }   
 
          if ( m_nbRow <= row )  
          {
               // je dois ajouter des rangées  
               std::vector<T>::iterator it = m_array.begin();
               m_array.insert(it+m_nbCol*m_nbRow, (row - m_nbRow + 1)*m_nbCol, m_neutralElement); 
               m_nbRow = row+1; 
          }  
 
          // puis je retourne simplement l'élément demandé.  
          return m_array[m_nbCol*row+col]; 
     }   
 
     // méthode clear: initialise tous les éléments de la matrice avec l'élément passé  
     // en paramètre.  
     void clear(const T &initElement = m_neutralElement)  
     {  
          std::vector<T>::iterator it; 
          for ( it = m_array.begin() ; it != m_array.end() ; ++it)  
               (*it) = initElement; 
     } 
};   
 
} //namespace 
 
#endif | 
Partager