Gestionnaire de listes
- typedef struct _list {
- int l;
- void **v;
- } *list;
Un type list est constitué d'une simple suite consécutive de pointeurs. l donne le nombre d'éléments dans la liste. v pointe sur une zone en mémoire assez grande pour contenir tous les éléments de la liste.
- extern list list_alloc( void );
- extern list list_init( list this );
- extern list list_new( void );
- extern void list_free( list this );
- extern int list_length( list this );
- extern void *list_get( list this, int key );
- extern void *list_put( list this, int key, void *val );
- extern void *list_delete( list this, int key );
- extern void *list_insert( list this, int key, void *val );
list_new retourne une nouvelle liste vide.
list_free désalloue la mémoire occupée par une liste.
list_length donne le nombre d'éléments contenus dans une liste.
list_get retourne un élément d'une liste.
list_put, list_insert et list_delete modifient le contenu d'une liste.
- list list_alloc( void ) {
- return (list)calloc( 1, sizeof ( struct _list ));
- }
- list list_init( list this ) {
- return this;
- }
- list list_new( void ) {
- return list_init( list_alloc() );
- }
- void list_free( list this ) {
- if ( this->v )
- free( this->v );
- free( this );
- }
list_new retourne une instance de list nouvellement allouée et initialisée.
list_alloc alloue la mémoire nécessaire à une liste et la retourne.
list_init retourne la liste this après l'avoir initialisée.
list_free libère la mémoire occupée par le tableau de pointeurs et la structure de la liste this.
- int list_length( list this ) {
- return this->l;
- }
list_length retourne le nombre d'éléments de la liste this.
- void *list_get( list this, int key ) {
- if ( key < 0 )
- return this->l ? this->v[ this->l - 1 ] : 0;
- else if ( key < this->l )
- return this->v[ key ];
- else
- return 0;
- }
list_get retourne l'élément de la liste this à la position key.
Si key est négatif, list_get retourne le dernier élément de la liste.
Si la liste est vide ou si key est supérieur à la longueur de la liste, list_get retourne 0.
- void *list_put( list this, int key, void *val ) {
- if ( key < 0 )
- key = this->l;
- if ( key < this->l )
- this->v[ key ] = val;
- else {
- this->l = key + 1;
- this->v = (void **)realloc( this->v, (key + 1) * sizeof ( void * ));
- this->v[ key ] = val;
- }
- return val;
- }
list_put place val à la position key dans la liste this. val est un pointeur quelconque.
Si key est négatif, val est ajouté à la fin de la liste.
Si la liste est vide ou si key est supérieur à la longueur de la liste, list_put alloue assez d'espace pour contenir key éléments et place val à la fin de la liste.
NOTE : realloc prend soin de copier les données si un nouveau bloc de mémoire est effectivement alloué.
list_put retourne val.
- void *list_delete( list this, int key ) {
- void **p, *val;
- if ( key < 0 )
- key = this->l ? this->l - 1 : 0;
- if ( key < this->l ) {
- val = this->v[ key ];
- this->l--;
- for ( p = this->v + key; p < this->v + this->l; p++ )
- *p = *(p+1);
- return val;
- }
- else
- return 0;
- }
list_delete supprime l'élément de la liste this à la position key.
Si key est négatif, list_delete supprime le dernier élément de la liste.
list_delete décrémente la longueur de la liste et décale tous les éléments de la liste vers la gauche à partir de key + 1. Tous les éléments après key changent d'index.
list_delete retourne l'élément supprimé ou 0 si la liste est vide ou si key est supérieur à la longueur de la liste.
- void *list_insert( list this, int key, void *val ) {
- void **p;
- if ( key < 0 || key >= this->l )
- return list_put( this, key, val );
- this->l++;
- this->v = (void **)realloc( this->v, this->l * sizeof ( void * ));
- for ( p = this->v + (this->l - 1); p > this->v + key; p-- )
- *p = *(p-1);
- this->v[ key ] = val;
- return val;
- }
list_insert insère l'élément val à la position key dans la liste this. val
Si key est négatif ou supérieur à la longueur de la liste, val est ajouté à la fin de la liste.
list_insert incrémente la longueur de la liste, alloue assez d'espace pour contenir un élément de plus, décale tous les éléments de la liste vers la droite à partir de key + 1 et place val à la position key. Tous les éléments après key changent d'index. NOTE : realloc prend soin de copier les données si un nouveau bloc de mémoire est effectivement alloué.
list_insert retourne l'élément ajouté.
Commentaires