#include #include #include #include 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; }