#include #include #include #include "zalloc.h" #include "systypes.h" #include "vector.h" static zv_vector_container_t * zv__vector_container_create(void) { zv_vector_container_t *created = (zv_vector_container_t *) zv_malloc(sizeof(zv_vector_container_t)); created->next = NULL; created->previous = NULL; return created; } static void zv__vector_container_drop(zv_vector_container_t *self) { zv_free(self); } static zv_vector_container_t * zv__vector_get_container( zv_vector_t *self, size_t index ) { if (self->length <= index) { return NULL; } if (index < self->length / 2) { zv_vector_container_t *current = self->first; while (index > 0) { current = current->next; --index; } return current; } zv_vector_container_t *current = self->last; index = self->length - index; while (index > 0) { current = current->previous; --index; } return current; } zv_vector_t * zv_vector_create(void) { zv_vector_t *self = (zv_vector_t *) zv_malloc(sizeof(zv_vector_t)); if (self == NULL) { return NULL; } self->length = 0x00; self->first = NULL; self->last = NULL; return self; } bool zv_vector_append(zv_vector_t *self, zv_universal_t content) { return zv_vector_insert(self, content, self->length); } zv_universal_t zv_vector_pop(zv_vector_t *self) { return zv_vector_indexed_pop(self, self->length - 1); } bool zv_vector_insert( zv_vector_t *self, zv_universal_t content, size_t index ) { if (index > self->length) { return false; } zv_vector_container_t *target = zv__vector_container_create(); if (target == NULL) { return false; } target->content = content; if (index == 0) { target->previous = NULL; target->next = self->first; self->first = target; ++self->length; return true; } if (index == self->length) { target->next = NULL; target->previous = self->last; self->last = target; ++self->length; return true; } target->previous = zv__vector_get_container(self, index - 1); target->next = target->previous->next; target->previous->next = target; target->next->previous = target; ++self->length; return true; } zv_universal_t zv_vector_indexed_pop(zv_vector_t *self, size_t index) { zv_vector_container_t *container = zv__vector_get_container(self, index); if (container == NULL) { return ZV_UNIVERSAL_NULL; } zv_universal_t content = container->content; if (index == 0) { self->first = container->next; self->first->previous = NULL; } if (index == self->length - 1) { self->last = container->previous; self->last->next = NULL; } if (index != 0 && index != self->length - 1) { container->next->previous = container->previous; container->previous->next = container->next; } --self->length; zv__vector_container_drop(container); return content; } void zv_vector_clear(zv_vector_t *self) { if (self->length == 0) { return; } zv_vector_container_t *current = self->first; while (current != NULL) { zv_vector_container_t *previous = current; current = current->next; zv__vector_container_drop(previous); } self->first = NULL; self->last = NULL; self->length = 0; } void zv_vector_remove(zv_vector_t *self) { zv_vector_clear(self); zv_free(self); }