cvec/vec.c

103 lines
2.2 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
typedef struct vec {
size_t len;
int capacity;
size_t element_size;
void* ptr;
} vec;
vec vecMalloc(size_t element_size) {
vec new;
new.len = 0;
new.capacity = 32;
new.element_size = element_size;
new.ptr = calloc(new.capacity, element_size);
if (new.ptr == NULL) new.capacity = -1;
return new;
}
#define vecNew(type) vecMalloc(sizeof(type))
void vecFree(vec* v) {
if (v->capacity < 0) return;
v->capacity = -1;
v->len = 0;
free(v->ptr);
}
// Returns 0 on success
int vecResize(vec* v, int newcap) {
void* newptr = calloc(newcap, v->element_size);
if (newptr == NULL) return 1;
memcpy(newptr, v->ptr, v->len * v->element_size);
void *oldptr = v->ptr;
v->ptr = newptr;
v->capacity = newcap;
free(oldptr);
return 0;
}
// returns 0 on success
int vecPush(vec* v, void* item) {
if (v->capacity < v->len) return 1;
if (v->len + 1 >= v->capacity) {
if (vecResize(v, v->capacity * 2)) return 1;
}
memcpy(v->ptr + (v->element_size * v->len), item, v->element_size);
v->len += 1;
return 0;
}
// returns NULL on failure
void* vecAt(vec* v, size_t index) {
if (index >= v->len) return NULL;
return v->ptr + (index * v->element_size);
}
// NOTE: returns 1 on success, 0 on failure. For use with loops.
int vecAtPtr(vec* v, size_t index, void** ptr) {
if(index >= v->len) return 0;
*ptr = v->ptr + (index * v->element_size);
return 1;
}
#define vecIter(v, type) for(struct{int i; type* item;} iter = {0, NULL}; vecAtPtr(&v, iter.i, (void**)&iter.item); ++iter.i)
int main(int argc, char *argv[]) {
printf("Hello World!\n");
char* str = "HI";
vec v = vecNew(char);
if(vecPush(&v, str)) {
printf("Error pushing %c\n", *str);
} else {
printf("Pushed %c\n", *str);
};
printf(vecPush(&v, str+1) ? "Error pushing %c\n" : "Pushed %c\n", *(str+1));
printf("vec len: %d\n", v.len);
printf("Iter fn\n");
vecIter(v, char) {
printf("%d: %c\n", iter.i, *iter.item);
}
printf("For loop\n");
for(size_t i = 0; i < v.len; i++) {
char* item = (char*)vecAt(&v, i);
printf("%d: %c\n", i, *item);
}
return EXIT_SUCCESS;
}