added vector lib
parent
603f390756
commit
179bbd8d4b
@ -0,0 +1,56 @@
|
|||||||
|
#include "vector.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "assert.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
|
||||||
|
Vector *v = NewVector(int, 1);
|
||||||
|
|
||||||
|
// Vector_Put(v, 0, 1);
|
||||||
|
// Vector_Put(v, 1, 3);
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
Vector_Push(v, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < Vector_Size(v); i++) {
|
||||||
|
int n;
|
||||||
|
int rc = Vector_Get(v, i, &n);
|
||||||
|
printf("%d %d\n", rc, n);
|
||||||
|
assert ( 1== rc );
|
||||||
|
assert (n == i);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector_Free(v);
|
||||||
|
|
||||||
|
v = NewVector(char *, 0);
|
||||||
|
int N = 4;
|
||||||
|
char *strings[4] = {"hello", "world", "foo", "bar"};
|
||||||
|
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
Vector_Push(v, strings[i]);
|
||||||
|
}
|
||||||
|
assert(Vector_Size(v) == N);
|
||||||
|
assert(Vector_Cap(v) >= N);
|
||||||
|
|
||||||
|
for (int i = 0; i < Vector_Size(v); i++) {
|
||||||
|
char *x;
|
||||||
|
int rc = Vector_Get(v, i, &x);
|
||||||
|
assert (rc == 1);
|
||||||
|
assert (!strcmp(x, strings[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = Vector_Get(v, 100, NULL);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
Vector_Free(v);
|
||||||
|
printf("PASS!");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
//Vector_Push(v, "hello");
|
||||||
|
//Vector_Push(v, "world");
|
||||||
|
// char *x = NULL;
|
||||||
|
// int rc = Vector_Getx(v, 0, &x);
|
||||||
|
// printf("rc: %d got %s\n", rc, x);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
#include "vector.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
int __vector_PushPtr(Vector *v, void *elem) {
|
||||||
|
if (v->top == v->cap - 1) {
|
||||||
|
Vector_Resize(v, v->cap ? v->cap*2 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
__vector_PutPtr(v, v->top, elem);
|
||||||
|
v->top++;
|
||||||
|
return v->top;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Vector_Get(Vector *v, int pos, void *ptr) {
|
||||||
|
if (pos >= v->top) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(ptr, v->data + (pos * v->elemSize), v->elemSize);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int __vector_PutPtr(Vector *v, int pos, void *elem) {
|
||||||
|
if (pos > v->cap) {
|
||||||
|
Vector_Resize(v, pos+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(v->data + pos*v->elemSize, elem, v->elemSize);
|
||||||
|
if (pos > v->top) {
|
||||||
|
v->top = pos;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Vector_Resize(Vector *v, int newcap) {
|
||||||
|
int oldcap = v->cap;
|
||||||
|
v->cap = newcap;
|
||||||
|
|
||||||
|
v->data = realloc(v->data, v->cap*v->elemSize);
|
||||||
|
int offset = v->top*v->elemSize;
|
||||||
|
memset(v->data + offset, 0, v->cap*v->elemSize - offset);
|
||||||
|
return v->cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vector *__newVectorSize(size_t elemSize, size_t cap) {
|
||||||
|
printf("allocating %zd elems of %zd size\n", cap, elemSize);
|
||||||
|
Vector *vec = malloc(sizeof(Vector));
|
||||||
|
vec->data = calloc(cap, elemSize);
|
||||||
|
vec->top = 0;
|
||||||
|
vec->elemSize = elemSize;
|
||||||
|
vec->cap = cap;
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vector_Free(Vector *v) {
|
||||||
|
free(v->data);
|
||||||
|
free(v);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
|||||||
|
#ifndef __VECTOR_H__
|
||||||
|
#define __VECTOR_H__
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic resizable vector that can be used if you just want to store stuff temporarily.
|
||||||
|
* Works like C++ std::vector with an underlying resizable buffer
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
char *data;
|
||||||
|
int elemSize;
|
||||||
|
int cap;
|
||||||
|
int top;
|
||||||
|
int isPtr;
|
||||||
|
} Vector;
|
||||||
|
|
||||||
|
// Create a new vector with element size. This should generally be used internall by the NewVector macro
|
||||||
|
Vector *__newVectorSize(size_t elemSize, size_t cap);
|
||||||
|
|
||||||
|
// Put a pointer in the vector. To be used internall by the library
|
||||||
|
int __vector_PutPtr(Vector *v, int pos, void *elem);
|
||||||
|
|
||||||
|
// Create a new vector for a given type and a given capacity.
|
||||||
|
// e.g. NewVector(int, 0) - empty vector of ints
|
||||||
|
#define NewVector(type, cap) __newVectorSize(sizeof(type), cap)
|
||||||
|
|
||||||
|
// get the element at index pos. The value is copied in to ptr. If pos is outside the vector capacity, we return 0
|
||||||
|
// otherwise 1
|
||||||
|
int Vector_Get(Vector *v, int pos, void *ptr);
|
||||||
|
|
||||||
|
//#define Vector_Getx(v, pos, ptr) pos < v->cap ? 1 : 0; *ptr = *(typeof(ptr))(v->data + v->elemSize*pos)
|
||||||
|
|
||||||
|
// Put an element at pos.
|
||||||
|
// Note: If pos is outside the vector capacity, we resize it accordingly
|
||||||
|
#define Vector_Put(v, pos, elem) __vector_PutPtr(v, pos, &(typeof(elem)){elem})
|
||||||
|
|
||||||
|
// Push an element at the end of v, resizing it if needed. This macro wraps __vector_PushPtr
|
||||||
|
#define Vector_Push(v, elem) __vector_PushPtr(v, &(typeof(elem)){elem})
|
||||||
|
|
||||||
|
int __vector_PushPtr(Vector *v, void *elem);
|
||||||
|
|
||||||
|
// resize capacity of v
|
||||||
|
int Vector_Resize(Vector *v, int newcap);
|
||||||
|
|
||||||
|
// return the used size of the vector, regardless of capacity
|
||||||
|
inline int Vector_Size(Vector *v) {
|
||||||
|
return v->top;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the actual capacity
|
||||||
|
inline int Vector_Cap(Vector *v) {
|
||||||
|
return v->cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// free the vector and the underlying data. Does not release its elements if they are pointers
|
||||||
|
void Vector_Free(Vector *v);
|
||||||
|
|
||||||
|
int __vecotr_PutPtr(Vector *v, int pos, void *elem);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue