implement vector
This commit is contained in:
parent
1f1ccddf82
commit
5251aa9e82
|
@ -12,6 +12,7 @@ set(SOURCES
|
||||||
src/binarytree.c
|
src/binarytree.c
|
||||||
src/input.c
|
src/input.c
|
||||||
src/math.c
|
src/math.c
|
||||||
|
src/vector.c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(flint ${SOURCES})
|
add_library(flint ${SOURCES})
|
||||||
|
|
|
@ -1,14 +1,6 @@
|
||||||
#ifndef LIBFLINT_H_UTILITY
|
#ifndef LIBFLINT_H_UTILITY
|
||||||
#define LIBFLINT_H_UTILITY
|
#define LIBFLINT_H_UTILITY
|
||||||
|
|
||||||
/**
|
|
||||||
* \struct Point
|
|
||||||
* \brief Representation of a point on a two dimensional grid
|
|
||||||
* \var int x
|
|
||||||
* x point on the 2d grid
|
|
||||||
* \var int y
|
|
||||||
* y point on the 2d grid
|
|
||||||
*/
|
|
||||||
typedef struct Point {
|
typedef struct Point {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef LIBFLINT_H_VECTOR
|
||||||
|
#define LIBFLINT_H_VECTOR
|
||||||
|
|
||||||
|
#include <memory.h>
|
||||||
|
|
||||||
|
typedef struct Vector {
|
||||||
|
size_t capacity;
|
||||||
|
size_t length;
|
||||||
|
void **elements;
|
||||||
|
void (*destroy)(void *data);
|
||||||
|
} Vector;
|
||||||
|
|
||||||
|
int vec_init(Vector *vec, void (*destroy)(void *data));
|
||||||
|
|
||||||
|
int vec_init_with_capacity(Vector *vec, void (*destroy)(void *data), size_t cap);
|
||||||
|
|
||||||
|
void vec_destroy(Vector *vec);
|
||||||
|
|
||||||
|
int vec_insert(Vector *vec, void *data, size_t index);
|
||||||
|
|
||||||
|
int vec_push(Vector *vec, void *data);
|
||||||
|
|
||||||
|
void *vec_safe_at(Vector *vec, size_t index);
|
||||||
|
|
||||||
|
void *vec_remove(Vector *vec, size_t index);
|
||||||
|
|
||||||
|
#define vec_at(v, i) (v)->elements[(i)]
|
||||||
|
|
||||||
|
#define vec_len(v) (v)->length
|
||||||
|
|
||||||
|
#endif // LIBFLINT_H_VECTOR
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
#define VEC_INIT_CAP 2
|
||||||
|
|
||||||
|
int vec_init(Vector *vec, void (*destroy)(void *data)) {
|
||||||
|
return vec_init_with_capacity(vec, destroy, VEC_INIT_CAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
int vec_init_with_capacity(Vector *vec, void (*destroy)(void *data), size_t capacity) {
|
||||||
|
if (vec == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
vec->destroy = destroy;
|
||||||
|
vec_len(vec) = 0;
|
||||||
|
vec->capacity = capacity;
|
||||||
|
vec->elements = malloc(sizeof (void*) * capacity);
|
||||||
|
if (vec->elements == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(vec->elements, 0, vec->capacity * sizeof(void *));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec_grow(Vector *const vec) {
|
||||||
|
vec->capacity *= 2;
|
||||||
|
vec->elements = reallocf(vec->elements, sizeof(void *) * vec->capacity);
|
||||||
|
if (vec->elements == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vec_destroy(Vector *vec) {
|
||||||
|
if (vec->destroy) {
|
||||||
|
for (size_t i = 0; i < vec_len(vec); ++i) {
|
||||||
|
vec->destroy(vec->elements[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(vec);
|
||||||
|
vec = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vec_insert(Vector *vec, void *data, size_t index) {
|
||||||
|
if (vec_len(vec) + 1 >= vec->capacity) {
|
||||||
|
if (vec_grow(vec) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index > vec_len(vec)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < vec_len(vec)) {
|
||||||
|
void *a = vec->elements[index];
|
||||||
|
vec->elements[index] = data;
|
||||||
|
|
||||||
|
void *b = NULL;
|
||||||
|
for (size_t i = index + 1; i <= vec_len(vec); ++i) {
|
||||||
|
b = vec->elements[i];
|
||||||
|
vec->elements[i] = a;
|
||||||
|
a = b;
|
||||||
|
}
|
||||||
|
} else /* index == vec_len(vec) */ {
|
||||||
|
vec->elements[index] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec_len(vec) += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vec_push(Vector *vec, void *data) {
|
||||||
|
return vec_insert(vec, data, vec_len(vec));
|
||||||
|
}
|
||||||
|
|
||||||
|
void *vec_safe_at(Vector *vec, size_t index) {
|
||||||
|
if (index >= vec_len(vec)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return vec->elements[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void *vec_remove(Vector *vec, size_t index) {
|
||||||
|
if (index >= vec_len(vec)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *r = vec_at(vec, index);
|
||||||
|
for (size_t i = index + 1; i < vec_len(vec); ++i) {
|
||||||
|
vec->elements[i - 1] = vec->elements[i];
|
||||||
|
}
|
||||||
|
vec->elements[vec_len(vec) - 1] = NULL;
|
||||||
|
vec->length -= 1;
|
||||||
|
return r;
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "linkedlist.h"
|
#include "linkedlist.h"
|
||||||
#include "set.h"
|
#include "set.h"
|
||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
#include "binarytree.h"
|
#include "binarytree.h"
|
||||||
|
#include "vector.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
void print_ll(List *list) {
|
void print_ll(List *list) {
|
||||||
|
@ -158,6 +160,7 @@ void test_bintree() {
|
||||||
void test_math() {
|
void test_math() {
|
||||||
printf("\n--- MATH TEST ---\n");
|
printf("\n--- MATH TEST ---\n");
|
||||||
int i = 1, j = 2;
|
int i = 1, j = 2;
|
||||||
|
assert(max_int(i, j) == j);
|
||||||
printf("Between %d and %d, %d is larger\n", i, j, max_int(i, j));
|
printf("Between %d and %d, %d is larger\n", i, j, max_int(i, j));
|
||||||
printf("Between %d and %d, %d is smaller\n", i, j, min_int(i, j));
|
printf("Between %d and %d, %d is smaller\n", i, j, min_int(i, j));
|
||||||
|
|
||||||
|
@ -179,11 +182,68 @@ void test_math() {
|
||||||
free(line);
|
free(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_vector(Vector *vec) {
|
||||||
|
for (size_t i = 0; i < vec->length; ++i) {
|
||||||
|
int t = *(int*)vec_at(vec, i);
|
||||||
|
printf("%d ", t);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_vector() {
|
||||||
|
printf("\n--- VECTOR TEST ---\n");
|
||||||
|
Vector *v = malloc(sizeof(Vector));
|
||||||
|
vec_init(v, NULL);
|
||||||
|
|
||||||
|
int e0 = 0;
|
||||||
|
int e1 = 1;
|
||||||
|
int e2 = 2;
|
||||||
|
int e3 = 3;
|
||||||
|
int e4 = 4;
|
||||||
|
|
||||||
|
vec_push(v, &e0);
|
||||||
|
assert(v->length == 1);
|
||||||
|
int *t = (int*)vec_at(v, 0);
|
||||||
|
assert(*t == 0);
|
||||||
|
|
||||||
|
vec_push(v, &e1);
|
||||||
|
vec_push(v, &e2);
|
||||||
|
assert(v->length == 3);
|
||||||
|
|
||||||
|
// test access outside bounds
|
||||||
|
t = (int*)vec_safe_at(v, 3);
|
||||||
|
assert(t == NULL);
|
||||||
|
|
||||||
|
printf("Before insert: ");
|
||||||
|
print_vector(v);
|
||||||
|
vec_push(v, &e4);
|
||||||
|
vec_insert(v, &e3, 3);
|
||||||
|
printf("After insert: ");
|
||||||
|
print_vector(v);
|
||||||
|
|
||||||
|
t = (int*)vec_at(v, 3);
|
||||||
|
assert(*t == e3);
|
||||||
|
t = (int*)vec_at(v, 4);
|
||||||
|
assert(*t == e4);
|
||||||
|
|
||||||
|
t = (int*)vec_remove(v, 1);
|
||||||
|
assert(t != NULL);
|
||||||
|
assert(*t == 1);
|
||||||
|
printf("After removal: ");
|
||||||
|
print_vector(v);
|
||||||
|
|
||||||
|
t = (int*)vec_remove(v, 10);
|
||||||
|
assert(t == NULL);
|
||||||
|
|
||||||
|
vec_destroy(v);
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
test_ll();
|
test_ll();
|
||||||
test_set();
|
test_set();
|
||||||
test_stack();
|
test_stack();
|
||||||
test_bintree();
|
test_bintree();
|
||||||
test_math();
|
test_math();
|
||||||
|
test_vector();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in New Issue