| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- #include <stdint.h>
- #include <stddef.h>
- #include <stdbool.h>
- #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);
- }
|