|
@@ -7,169 +7,137 @@
|
|
|
|
|
|
|
|
#include "vector.h"
|
|
#include "vector.h"
|
|
|
|
|
|
|
|
|
|
+zv_vector_t * zv_vector_create(void) {
|
|
|
|
|
+ return (zv_vector_t *) zv_malloc(sizeof(zv_vector_t));
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-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));
|
|
|
|
|
|
|
+void zv_vector_clear(zv_vector_t *self) {
|
|
|
|
|
+ if (*self == NULL) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- created->next = NULL;
|
|
|
|
|
- created->previous = NULL;
|
|
|
|
|
|
|
+void zv_vector_remove(zv_vector_t *self) {
|
|
|
|
|
+ zv_vector_clear(self);
|
|
|
|
|
|
|
|
- return created;
|
|
|
|
|
|
|
+ zv_free(self);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void zv__vector_container_drop(zv_vector_container_t *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;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static zv_vector_container_t * zv__vector_get_container(
|
|
|
|
|
|
|
+zv_vector_container_t * zv_vector_get_container(
|
|
|
zv_vector_t *self,
|
|
zv_vector_t *self,
|
|
|
- size_t index
|
|
|
|
|
|
|
+ zv_vector_count_t index
|
|
|
) {
|
|
) {
|
|
|
- if (self->length <= index) {
|
|
|
|
|
|
|
+ if (*self == NULL) {
|
|
|
return NULL;
|
|
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;
|
|
|
|
|
|
|
+ zv_vector_container_t *current = *self;
|
|
|
|
|
|
|
|
- index = self->length - index;
|
|
|
|
|
|
|
+ while (index > 0 && current != NULL) {
|
|
|
|
|
+ current = current->next;
|
|
|
|
|
+ --index;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- while (index > 0) {
|
|
|
|
|
|
|
+ while (index < 0 && current != NULL) {
|
|
|
current = current->previous;
|
|
current = current->previous;
|
|
|
- --index;
|
|
|
|
|
|
|
+ ++index;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return current;
|
|
return current;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-zv_vector_t * zv_vector_create(void) {
|
|
|
|
|
- zv_vector_t *self = (zv_vector_t *) zv_malloc(sizeof(zv_vector_t));
|
|
|
|
|
|
|
+zv_universal_t zv_vector_pop(zv_vector_t *self) {
|
|
|
|
|
+ return zv_vector_indexed_pop(self, -1);
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- if (self == NULL) {
|
|
|
|
|
- return NULL;
|
|
|
|
|
|
|
+zv_universal_t zv_vector_indexed_pop(
|
|
|
|
|
+ zv_vector_t *self,
|
|
|
|
|
+ zv_vector_count_t index
|
|
|
|
|
+) {
|
|
|
|
|
+ if (*self == NULL) {
|
|
|
|
|
+ return ZV_UNIVERSAL_NULL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- self->length = 0x00;
|
|
|
|
|
- self->first = NULL;
|
|
|
|
|
- self->last = NULL;
|
|
|
|
|
|
|
+ zv_vector_container_t *current = *self;
|
|
|
|
|
|
|
|
- return self;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-bool zv_vector_append(zv_vector_t *self, zv_universal_t content) {
|
|
|
|
|
- return zv_vector_insert(self, content, self->length);
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ if (current->next == current) {
|
|
|
|
|
+ *self = NULL;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-zv_universal_t zv_vector_pop(zv_vector_t *self) {
|
|
|
|
|
- return zv_vector_indexed_pop(self, self->length - 1);
|
|
|
|
|
|
|
+ return ZV_UNIVERSAL_NULL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool zv_vector_insert(
|
|
bool zv_vector_insert(
|
|
|
zv_vector_t *self,
|
|
zv_vector_t *self,
|
|
|
zv_universal_t content,
|
|
zv_universal_t content,
|
|
|
- size_t index
|
|
|
|
|
|
|
+ zv_vector_count_t index
|
|
|
) {
|
|
) {
|
|
|
- if (index > self->length) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ zv_vector_container_t *target = zv_malloc(sizeof(zv_vector_container_t));
|
|
|
|
|
|
|
|
- zv_vector_container_t *target = zv__vector_container_create();
|
|
|
|
|
-
|
|
|
|
|
if (target == NULL) {
|
|
if (target == NULL) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
target->content = content;
|
|
target->content = content;
|
|
|
|
|
+
|
|
|
|
|
+ if (*self == NULL) {
|
|
|
|
|
+ *self = target;
|
|
|
|
|
+ target->next = target;
|
|
|
|
|
+ target->previous = target;
|
|
|
|
|
|
|
|
- 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;
|
|
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_vector_container_t *current = *self;
|
|
|
|
|
+ bool overwrite_handler = (index == 0);
|
|
|
|
|
|
|
|
- zv_universal_t content = container->content;
|
|
|
|
|
-
|
|
|
|
|
- if (index == 0) {
|
|
|
|
|
- self->first = container->next;
|
|
|
|
|
- self->first->previous = NULL;
|
|
|
|
|
|
|
+ while (index > 0 && current != NULL) {
|
|
|
|
|
+ current = current->next;
|
|
|
|
|
+ --index;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (index == self->length - 1) {
|
|
|
|
|
- self->last = container->previous;
|
|
|
|
|
- self->last->next = NULL;
|
|
|
|
|
|
|
+ while (index < -1 && current != NULL) {
|
|
|
|
|
+ current = current->previous;
|
|
|
|
|
+ ++index;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (index != 0 && index != self->length - 1) {
|
|
|
|
|
- container->next->previous = container->previous;
|
|
|
|
|
- container->previous->next = container->next;
|
|
|
|
|
|
|
+ if (current == NULL) {
|
|
|
|
|
+ zv_free(target);
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- --self->length;
|
|
|
|
|
- zv__vector_container_drop(container);
|
|
|
|
|
-
|
|
|
|
|
- return content;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void zv_vector_clear(zv_vector_t *self) {
|
|
|
|
|
- if (self->length == 0) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ target->next = current;
|
|
|
|
|
+ target->previous = current->previous;
|
|
|
|
|
|
|
|
- zv_vector_container_t *current = self->first;
|
|
|
|
|
|
|
+ current->previous->next = target;
|
|
|
|
|
+ current->previous = target;
|
|
|
|
|
|
|
|
- while (current != NULL) {
|
|
|
|
|
- zv_vector_container_t *previous = current;
|
|
|
|
|
- current = current->next;
|
|
|
|
|
-
|
|
|
|
|
- zv__vector_container_drop(previous);
|
|
|
|
|
|
|
+ if (overwrite_handler) {
|
|
|
|
|
+ *self = target;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- self->first = NULL;
|
|
|
|
|
- self->last = NULL;
|
|
|
|
|
- self->length = 0;
|
|
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void zv_vector_remove(zv_vector_t *self) {
|
|
|
|
|
- zv_vector_clear(self);
|
|
|
|
|
- zv_free(self);
|
|
|
|
|
|
|
+bool zv_vector_append(zv_vector_t *self, zv_universal_t content) {
|
|
|
|
|
+ return zv_vector_insert(self, content, -1);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+
|