#include #include #include #include "zalloc.h" #include "systypes.h" #include "vector.h" zv_vector_t * zv_vector_create(void) { return (zv_vector_t *) zv_malloc(sizeof(zv_vector_t)); } void zv_vector_clear(zv_vector_t *self) { if (*self == NULL) { return; } } void zv_vector_remove(zv_vector_t *self) { zv_vector_clear(self); zv_free(self); } zv_vector_count_t zv_vector_length(zv_vector_t *self) { if (*self == NULL) { return 0; } zv_vector_container_t *first = *self; zv_vector_container_t *current = first; zv_vector_count_t size = 1; while (current->next != first) { ++size; current = current->next; } return size; } zv_vector_container_t * zv_vector_get_container( zv_vector_t *self, zv_vector_count_t index ) { if (*self == NULL) { return NULL; } zv_vector_container_t *current = *self; while (index > 0 && current != NULL) { current = current->next; --index; } while (index < 0 && current != NULL) { current = current->previous; ++index; } return current; } zv_universal_t zv_vector_pop(zv_vector_t *self) { return zv_vector_indexed_pop(self, -1); } zv_universal_t zv_vector_indexed_pop( zv_vector_t *self, zv_vector_count_t index ) { if (*self == NULL) { return ZV_UNIVERSAL_NULL; } zv_vector_container_t *current = *self; if (current->next == current) { *self = NULL; } return ZV_UNIVERSAL_NULL; } bool zv_vector_insert( zv_vector_t *self, zv_universal_t content, zv_vector_count_t index ) { zv_vector_container_t *target = zv_malloc(sizeof(zv_vector_container_t)); if (target == NULL) { return false; } target->content = content; if (*self == NULL) { *self = target; target->next = target; target->previous = target; return true; } zv_vector_container_t *current = *self; bool overwrite_handler = (index == 0); while (index > 0 && current != NULL) { current = current->next; --index; } while (index < -1 && current != NULL) { current = current->previous; ++index; } if (current == NULL) { zv_free(target); return false; } target->next = current; target->previous = current->previous; current->previous->next = target; current->previous = target; if (overwrite_handler) { *self = target; } return true; } bool zv_vector_append(zv_vector_t *self, zv_universal_t content) { return zv_vector_insert(self, content, -1); }