Initial implementation
This commit is contained in:
commit
a78acfc09c
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
a.out
|
||||
102
vec.c
Normal file
102
vec.c
Normal file
@ -0,0 +1,102 @@
|
||||
#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;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user