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
| class ColonneAbstraite
{
public:
virtual ~ColonneAbstraite() {}
virtual void ajouteElement(Tableau& parent, size_t indiceDeMoiMemeDansParent, const std::string& valeur) = 0;
// Si la valeur n'a pas le bon type, créer une nouvelle colonne,
// l'insérer dans le tableau à notre place et se suicider.
// ...
};
class Tableau
{
private:
std::vector<std::unique_ptr<ColonneAbstraite>> m_colonnes;
public:
std::unique_ptr<ColonneAbstraite> libererColonne(size_t indice) {
assert(indice < m_colonnes.size());
return std::move(m_colonnes[indice]);
}
void setColonne(size_t indiceColonne, std::unique_ptr<ColonneAbstraite> nouvelleColonne) {
assert(indiceColonne < m_colonnes.size());
m_colonnes[indiceColonne] = std::move(nouvelleColonne);
}
void ajouteElement(size_t indiceColonne, const std::string& valeur) {
assert(indiceColonne < m_colonnes.size());
m_colonnes[indiceColonne]->ajouteElement(*this, indiceColonne, valeur);
}
// ...
};
class ColonneChaines : public ColonneAbstraite { /* ... */ };
class ColonneEntiers : public ColonneAbstraite { /* ... */ };
class ColonneBooleens : public ColonneAbstraite
{
private:
std::vector<bool> m_cellules;
public:
virtual ~ColonneBooleens() {}
void ajouteElement(Tableau& parent, size_t indiceDeMoiMemeDansParent, const std::string& valeur) override
{
boost::optional<bool> valeurBooleenne = convertirEnBooleen(valeur);
if(valeurBooleenne) {
m_cellules.push_back(*valeurBooleenne);
} else {
std::unique_ptr<ColonneAbstraite> nouvelleColonne;
boost::optional<int> valeurEntiere = convertirEnEntier(valeur);
if(valeurEntiere) {
std::unique_ptr<ColonneEntiers> nouvelleColonneEntiers(new ColonneEntiers(*this));
nouvelleColonneEntiers->ajouterEntier(*valeurEntiere);
nouvelleColonne = std::move(nouvelleColonneEntiers);
} else {
std::unique_ptr<ColonneChaines> nouvelleColonneChaines(new ColonneChaines(*this));
nouvelleColonneChaines->ajouterChaine(valeur);
nouvelleColonne = std::move(nouvelleColonneChaines);
}
std::unique_ptr<ColonneAbstraite> moi = parent.libererColonne(indiceDeMoiMemeDansParent);
assert(moi.get() == this);
parent.setColonne(indiceDeMoiMemeDansParent, std::move(nouvelleColonne));
}
}
// ...
}; |
Partager