sim_ressorts/labo01/DenseStorage.h

205 lines
5.1 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
/**
* @file DenseStorage.h
*
* @brief Stockage dense pour des données à taille fixe ou dynamique.
*
* Nom: William Nolin
* Code permanent : NOLW76060101
* Email : william.nolin.1@ens.etsmtl.ca
*
*/
#include <cstring>
#include <cassert>
namespace gti320 {
enum SizeType {
Dynamic = -1
};
/**
* 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>
class DenseStorage {
private:
_Scalar m_data[_Size];
public:
/**
* Constructeur par défaut
*/
DenseStorage() {}
/**
* Constructeur de copie
*/
DenseStorage(const DenseStorage &other) {
memcpy(m_data, other.m_data, sizeof(m_data));
}
/**
* Constructeur avec taille spécifiée
*
* (doit être la même que la taille spécifiée dans le patron)
*/
explicit DenseStorage(int _size) {
}
/**
* Constructor avec taille (_size) et données initiales (_data).
*/
explicit DenseStorage(const _Scalar *_data, int _size) {
assert(_size >= 0 && _size == _Size);
memcpy(m_data, _data, sizeof(_Scalar) * _size);
}
/**
* Opérateur de copie
*/
DenseStorage &operator=(const DenseStorage &other) {
if (this != &other) {
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.
*/
void resize(int size) {
// Ne rien faire. Invalide pour les matrices à taille fixe.
}
/**
* Mets tous les éléments à zéro.
*/
void setZero() {
memset(m_data, 0, sizeof(_Scalar) * _Size);
}
/**
* Accès au tampon de données (en lecteur seulement)
*/
const _Scalar *data() const {
return &m_data[0];
}
/**
* Accès au tampon de données (pour lecture et écriture)
*/
_Scalar *data() {
return &m_data[0];
}
};
/**
* 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>
class DenseStorage<_Scalar, Dynamic> {
private:
_Scalar *m_data;
int m_size;
public:
/**
* Constructeur par défaut
*/
DenseStorage() : m_data(nullptr), m_size(0) {}
/**
* Constructeur avec taille spécifiée
*/
explicit DenseStorage(int _size) : m_data(new _Scalar[_size]), m_size(_size) {
setZero();
}
/**
* Constructeur de copie
*/
DenseStorage(const DenseStorage &other)
: m_data(new _Scalar[other.m_size]), m_size(other.m_size) {
memcpy(m_data, other.m_data, m_size * sizeof(_Scalar));
}
/**
* Opérateur de copie
*/
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));
return *this;
}
/**
* Destructeur
*/
~DenseStorage() {
delete[] m_data;
}
/**
* 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.
*
* 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.
*/
void resize(int _size) {
auto *data = new _Scalar[_size];
delete[] m_data;
m_data = data;
m_size = _size;
setZero();
}
/**
* Met tous les éléments à zéro.
*/
void setZero() {
memset(m_data, 0, m_size * sizeof(_Scalar));
}
/**
* Accès au tampon de données (en lecteur seulement)
*/
const _Scalar *data() const { return m_data; }
/**
* Accès au tampon de données (pour lecture et écriture)
*/
_Scalar *data() { return m_data; }
};
}