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