Dynamically sized vector in C, implemented using fat pointers.
Forewarning: This is probably the hackiest project I have ever written, I mainly wrote it for fun/as an exercise, so the performance may not be fantastic (though, from my experience, it is quite fast). If performance is the goal, use fvec_pop_back and FVEC_NO_RESIZE mode (other fvec_pop_* functions use memcpy to shift elements in O(n) time).
Standard example with automatic reallocations:
#include<stdio.h>#defineFVEC_IMPLEMENTATION#include"fvec.h"#undef FVEC_IMPLEMENTATION
voidtriple(void*i) {
*(int*)i *= 3;
}
voidsum(void*curr, void*rsf) {
*(int*)rsf+=*(int*)curr;
}
intis_odd(void*i) {
return*(int*)i % 2==1;
}
voidprint(void*i) {
printf("%d ", *(int*)i);
}
intmain(void) {
int*data=fvec(sizeof(int));
*(int*)fvec_push(&data) =0;
*(int*)fvec_push(&data) =1;
*(int*)fvec_push(&data) =2;
*(int*)fvec_push(&data) =3;
*(int*)fvec_push(&data) =4;
*(int*)fvec_push(&data) =5;
fvec_pop(&data, 2); // removes element at index 2 (2), now [0, 1, 3, 4, 5]fvec_pop_back(&data); // removes last (5), now [0, 1, 3, 4], length = 4fvec_pop_front(&data); // removes first (0), now [1, 3, 4], length = 3// map a function to triple all values in the vectorfvec_map(data, triple); // [1, 3, 4] -> [3, 9, 12]// fold a binary function over data to sum all valuesintresult=0;
fvec_fold(data, &result, sum); // <result> + 3 + 9 + 12 = 24printf("Result is: %d\n", result);
// create a new vector filled with all odd numbers in dataint*odds=fvec(sizeof(int));
fvec_filter(data, &odds, is_odd);
// print the vectorsfvec_print(data, print);
fvec_print(odds, print);
// free the data behind the vectorsfvec_free(&data);
fvec_free(&odds);
return0;
}Example without automatic reallocations:
#include<stdio.h>#defineFVEC_IMPLEMENTATION#defineFVEC_NO_RESIZE#include"fvec.h"#undef FVEC_IMPLEMENTATION
intmain(void) {
// cap will be made highest closest power of 2// ie.. 33 <= x <= 64 -> capacity = 64// or alternatively;// capacity = 2^(n-1)+1 <= x <= 2^n = 2^nint*data=fvecci(sizeof(int), 60); // capacity will be set to 64// fill vectorfor(inti=0; i<fvec_capacity(data); ++i)
*(int*)fvec_push(&data) =i;
// remove back half of the elements; need to shrink uneccessary allocationfor(inti=0; i<fvec_capacity(data) / 2; ++i)
fvec_pop_back(&data);
printf("Initial cap %d, len: %d\n", fvec_capacity(data), fvec_length(data));
// "Initial cap 64, len: 32\n" (cap is always a power of 2)// shrink the allocation to fit current lengthfvec_shrink_to_fit(&data);
printf("After cap %d, len: %d\n", fvec_capacity(data), fvec_length(data));
// "After cap 32, len: 32\n"fvec_free(&data);
return0;
}Run with make