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 |