added vector lib

master
Dvir Volk 9 years ago
parent 603f390756
commit 179bbd8d4b

@ -6,7 +6,7 @@ endif
CFLAGS = -g -fPIC -lc -lm -O3 -std=gnu99 -I$(RM_INCLUDE_DIR) CFLAGS = -g -fPIC -lc -lm -O3 -std=gnu99 -I$(RM_INCLUDE_DIR)
CC=gcc CC=gcc
OBJS=util.o strings.o sds.o OBJS=util.o strings.o sds.o vector.o
all: librmutil.a all: librmutil.a
@ -16,3 +16,8 @@ clean:
librmutil.a: $(OBJS) librmutil.a: $(OBJS)
ar rcs $@ $^ ar rcs $@ $^
test_vector: test_vector.o vector.o
$(CC) -o test_vector vector.o test_vector.o -lc -O0
@(sh -c ./test_vector)

@ -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…
Cancel
Save