Lists are good
This commit is contained in:
parent
05c55837fb
commit
64ec8a8e5a
2 changed files with 247 additions and 0 deletions
64
include/patty/list.h
Normal file
64
include/patty/list.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
#ifndef _PATTY_LIST_H
|
||||
#define _PATTY_LIST_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef struct _patty_list_item {
|
||||
struct _patty_list_item * prev;
|
||||
struct _patty_list_item * next;
|
||||
|
||||
void * value;
|
||||
} patty_list_item;
|
||||
|
||||
typedef struct _patty_list {
|
||||
uint64_t size;
|
||||
uint64_t length;
|
||||
|
||||
patty_list_item * first;
|
||||
patty_list_item * last;
|
||||
} patty_list;
|
||||
|
||||
typedef struct _patty_list_iterator {
|
||||
patty_list *list;
|
||||
|
||||
size_t index;
|
||||
patty_list_item * item;
|
||||
} patty_list_iterator;
|
||||
|
||||
typedef void (*patty_list_callback)(void *item, void *ctx);
|
||||
|
||||
patty_list *patty_list_new();
|
||||
|
||||
void patty_list_destroy(patty_list *list);
|
||||
|
||||
size_t patty_list_length(patty_list *list);
|
||||
|
||||
void *patty_list_set(patty_list *list, off_t index, void *item);
|
||||
|
||||
void *patty_list_append(patty_list *list, void *item);
|
||||
|
||||
void *patty_list_prepend(patty_list *list, void *item);
|
||||
|
||||
void *patty_list_last(patty_list *list);
|
||||
|
||||
void *patty_list_pop(patty_list *list);
|
||||
|
||||
void *patty_list_insert(patty_list *list, off_t index);
|
||||
|
||||
void *patty_list_index(patty_list *list, off_t index);
|
||||
|
||||
patty_list_iterator *patty_list_start(patty_list *list);
|
||||
|
||||
void *patty_list_next(patty_list_iterator *iterator);
|
||||
|
||||
void patty_list_reset(patty_list_iterator *iterator);
|
||||
|
||||
void patty_list_finish(patty_list_iterator *iterator);
|
||||
|
||||
void patty_list_each(
|
||||
patty_list * list,
|
||||
patty_list_callback callback,
|
||||
void * ctx);
|
||||
|
||||
#endif /* _PATTY_LIST_H */
|
183
src/list.c
Normal file
183
src/list.c
Normal file
|
@ -0,0 +1,183 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <patty/list.h>
|
||||
|
||||
patty_list *patty_list_new() {
|
||||
patty_list *list;
|
||||
|
||||
if ((list = malloc(sizeof(*list))) == NULL) {
|
||||
goto error_malloc_list;
|
||||
}
|
||||
|
||||
list->length = 0;
|
||||
list->size = 0;
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
|
||||
return list;
|
||||
|
||||
error_malloc_list:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void patty_list_destroy(patty_list *list) {
|
||||
patty_list_item *item = list->first;
|
||||
|
||||
while (item != NULL) {
|
||||
patty_list_item *next = (patty_list_item *)item->next;
|
||||
|
||||
free(item);
|
||||
|
||||
item = next;
|
||||
}
|
||||
|
||||
free(list);
|
||||
}
|
||||
|
||||
size_t patty_list_length(patty_list *list) {
|
||||
return list->length;
|
||||
}
|
||||
|
||||
void *patty_list_set(patty_list *list, off_t index, void *value) {
|
||||
patty_list_item *item = list->first;
|
||||
size_t i = 0;
|
||||
|
||||
while (item != NULL) {
|
||||
if (i++ == index) {
|
||||
return item->value = value;
|
||||
}
|
||||
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *patty_list_append(patty_list *list, void *value) {
|
||||
patty_list_item *item = list->first;
|
||||
patty_list_item *new;
|
||||
|
||||
if ((new = malloc(sizeof(*new))) == NULL) {
|
||||
goto error_malloc_item;
|
||||
}
|
||||
|
||||
new->value = value;
|
||||
|
||||
if (list->first == NULL) {
|
||||
list->first = new;
|
||||
} else {
|
||||
for (item = list->first; item->next != NULL; item = item->next);
|
||||
|
||||
item->next = new;
|
||||
}
|
||||
|
||||
list->length++;
|
||||
|
||||
return value;
|
||||
|
||||
error_malloc_item:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *patty_list_last(patty_list *list) {
|
||||
patty_list_item *item = list->first;
|
||||
|
||||
while (item->next != NULL) {
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
return item->value;
|
||||
}
|
||||
|
||||
void *patty_list_pop(patty_list *list) {
|
||||
patty_list_item *item = list->first;
|
||||
patty_list_item *last = NULL;
|
||||
|
||||
while (item != NULL) {
|
||||
if (item->next == NULL) {
|
||||
void *ret = item->value;
|
||||
|
||||
if (last == NULL) {
|
||||
list->first = NULL;
|
||||
} else {
|
||||
last->next = NULL;
|
||||
}
|
||||
|
||||
free(item);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
last = item;
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *patty_list_index(patty_list *list, off_t index) {
|
||||
patty_list_item *item = list->first;
|
||||
size_t i = 0;
|
||||
|
||||
if (index < 0) {
|
||||
index += list->length;
|
||||
|
||||
}
|
||||
|
||||
if (index >= list->length || index < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (i < index && item->next != NULL) {
|
||||
item = item->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
return item->value;
|
||||
}
|
||||
|
||||
patty_list_iterator *patty_list_start(patty_list *list) {
|
||||
patty_list_iterator *iterator;
|
||||
|
||||
if ((iterator = malloc(sizeof(patty_list_iterator))) == NULL) {
|
||||
goto error_malloc;
|
||||
}
|
||||
|
||||
iterator->list = list;
|
||||
iterator->item = list->first;
|
||||
|
||||
return iterator;
|
||||
|
||||
error_malloc:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *patty_list_next(patty_list_iterator *iterator) {
|
||||
void *value = NULL;
|
||||
|
||||
if (iterator->item) {
|
||||
value = iterator->item->value;
|
||||
|
||||
iterator->item = iterator->item->next;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void patty_list_reset(patty_list_iterator *iterator) {
|
||||
iterator->item = iterator->list->first;
|
||||
}
|
||||
|
||||
void patty_list_finish(patty_list_iterator *iterator) {
|
||||
free(iterator);
|
||||
}
|
||||
|
||||
void patty_list_each(patty_list *list, patty_list_callback callback, void *ctx) {
|
||||
patty_list_item *item;
|
||||
|
||||
for (item = list->first; item != NULL; item = item->next) {
|
||||
callback(item->value, ctx);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue