sim_ressorts/labo01/DenseStorage.h

205 lines
5.1 KiB
C
Raw Normal View History

2024-02-27 13:20:47 -05:00
#pragma once
/**
* @file DenseStorage.h
*
* @brief Stockage dense pour des données à taille fixe ou dynamique.
*
2024-02-27 13:27:05 -05:00
* Nom: William Nolin
* Code permanent : NOLW76060101
* Email : william.nolin.1@ens.etsmtl.ca
2024-02-27 13:20:47 -05:00
*
*/
#include <cstring>
#include <cassert>
2024-02-27 13:27:05 -05:00
namespace gti320 {
enum SizeType {
Dynamic = -1
};
2024-02-27 13:20:47 -05:00
/**
* Stockage à taille fixe.
*
* Le nombre de données à stocker est connu au moment de la compilation.
* Ce nombre est donné par le paramètre de patron : _Size
*
* Un tampon (tableau) de taille `_Size_` est alloué sur la pile d'exécution.
*/
template<typename _Scalar, int _Size>
2024-02-27 13:27:05 -05:00
class DenseStorage {
2024-02-27 13:20:47 -05:00
private:
2024-02-27 13:27:05 -05:00
_Scalar m_data[_Size];
2024-02-27 13:20:47 -05:00
public:
/**
* Constructeur par défaut
*/
2024-02-27 13:27:05 -05:00
DenseStorage() {}
2024-02-27 13:20:47 -05:00
/**
* Constructeur de copie
*/
2024-02-27 13:27:05 -05:00
DenseStorage(const DenseStorage &other) {
2024-02-27 13:20:47 -05:00
memcpy(m_data, other.m_data, sizeof(m_data));
}
/**
2024-02-27 13:27:05 -05:00
* Constructeur avec taille spécifiée
2024-02-27 13:20:47 -05:00
*
2024-02-27 13:27:05 -05:00
* (doit être la même que la taille spécifiée dans le patron)
2024-02-27 13:20:47 -05:00
*/
2024-02-27 13:27:05 -05:00
explicit DenseStorage(int _size) {
2024-02-27 13:20:47 -05:00
}
/**
2024-02-27 13:27:05 -05:00
* Constructor avec taille (_size) et données initiales (_data).
2024-02-27 13:20:47 -05:00
*/
2024-02-27 13:27:05 -05:00
explicit DenseStorage(const _Scalar *_data, int _size) {
2024-02-27 13:20:47 -05:00
assert(_size >= 0 && _size == _Size);
memcpy(m_data, _data, sizeof(_Scalar) * _size);
}
/**
* Opérateur de copie
*/
2024-02-27 13:27:05 -05:00
DenseStorage &operator=(const DenseStorage &other) {
if (this != &other) {
2024-02-27 13:20:47 -05:00
assert(other.size() == _Size);
memcpy(m_data, other.m_data, sizeof(m_data));
}
return *this;
}
static int size() { return _Size; }
/**
* Redimensionne le stockage pour qu'il contienne `size` élément.
*/
2024-02-27 13:27:05 -05:00
void resize(int size) {
2024-02-27 13:20:47 -05:00
// Ne rien faire. Invalide pour les matrices à taille fixe.
}
/**
* Mets tous les éléments à zéro.
*/
2024-02-27 13:27:05 -05:00
void setZero() {
2024-02-27 13:20:47 -05:00
memset(m_data, 0, sizeof(_Scalar) * _Size);
}
/**
* Accès au tampon de données (en lecteur seulement)
*/
2024-02-27 13:27:05 -05:00
const _Scalar *data() const {
return &m_data[0];
2024-02-27 13:20:47 -05:00
}
/**
* Accès au tampon de données (pour lecture et écriture)
*/
2024-02-27 13:27:05 -05:00
_Scalar *data() {
return &m_data[0];
2024-02-27 13:20:47 -05:00
}
};
/**
* Stockage à taille dynamique.
*
* Le nombre de données à stocker est déterminé à l'exécution.
* Un tampon de la taille demandée doit être alloué sur le tas via
* l'opérateur `new []` et la mémoire doit être libérée avec `delete[]`
*/
template<typename _Scalar>
2024-02-27 13:27:05 -05:00
class DenseStorage<_Scalar, Dynamic> {
2024-02-27 13:20:47 -05:00
private:
2024-02-27 13:27:05 -05:00
_Scalar *m_data;
2024-02-27 13:20:47 -05:00
int m_size;
public:
/**
* Constructeur par défaut
*/
DenseStorage() : m_data(nullptr), m_size(0) {}
/**
* Constructeur avec taille spécifiée
*/
2024-02-27 13:27:05 -05:00
explicit DenseStorage(int _size) : m_data(new _Scalar[_size]), m_size(_size) {
setZero();
2024-02-27 13:20:47 -05:00
}
/**
* Constructeur de copie
*/
2024-02-27 13:27:05 -05:00
DenseStorage(const DenseStorage &other)
: m_data(new _Scalar[m_size]), m_size(other.m_size) {
memcpy(m_data, other.m_data, m_size * sizeof(_Scalar));
2024-02-27 13:20:47 -05:00
}
/**
* Opérateur de copie
*/
2024-02-27 13:27:05 -05:00
DenseStorage &operator=(const DenseStorage &other) {
if (m_size != other.size()) {
resize(other.size());
}
m_size = other.m_size;
memcpy(m_data, other.m_data, m_size * sizeof(_Scalar));
2024-02-27 13:20:47 -05:00
return *this;
}
/**
* Destructeur
*/
2024-02-27 13:27:05 -05:00
~DenseStorage() {
delete[] m_data;
2024-02-27 13:20:47 -05:00
}
/**
* Retourne la taille du tampon
*/
inline int size() const { return m_size; }
/**
* Redimensionne le tampon alloué pour le stockage.
* La mémoire qui n'est plus utilisée doit être libérée.
2024-02-27 13:27:05 -05:00
*
2024-02-27 13:20:47 -05:00
* Note : Toutes opérations de redimensionnement entraînent une réallocation de mémoire.
* Il nest pas pertinent de copier les données car le résultat serait de toute façon incohérent.
*/
2024-02-27 13:27:05 -05:00
void resize(int _size) {
auto *data = new _Scalar[_size];
delete[] m_data;
m_data = data;
m_size = _size;
2024-02-27 13:20:47 -05:00
2024-02-27 13:27:05 -05:00
setZero();
2024-02-27 13:20:47 -05:00
}
/**
* Met tous les éléments à zéro.
*/
2024-02-27 13:27:05 -05:00
void setZero() {
memset(m_data, 0, m_size * sizeof(_Scalar));
2024-02-27 13:20:47 -05:00
}
/**
* Accès au tampon de données (en lecteur seulement)
*/
2024-02-27 13:27:05 -05:00
const _Scalar *data() const { return m_data; }
2024-02-27 13:20:47 -05:00
/**
* Accès au tampon de données (pour lecture et écriture)
*/
2024-02-27 13:27:05 -05:00
_Scalar *data() { return m_data; }
2024-02-27 13:20:47 -05:00
};
}