103 lines
2.2 KiB
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;
|
|
}
|