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> #define FVEC_IMPLEMENTATION #include "fvec.h" #undef FVEC_IMPLEMENTATION void triple(void *i) { *(int*)i *= 3; } void sum(void *curr, void *rsf) { *(int*)rsf += *(int*)curr; } int is_odd(void *i) { return *(int*)i % 2 == 1; } void print(void *i) { printf("%d ", *(int*)i); } int main(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 = 4 fvec_pop_front(&data); // removes first (0), now [1, 3, 4], length = 3 // map a function to triple all values in the vector fvec_map(data, triple); // [1, 3, 4] -> [3, 9, 12] // fold a binary function over data to sum all values int result = 0; fvec_fold(data, &result, sum); // <result> + 3 + 9 + 12 = 24 printf("Result is: %d\n", result); // create a new vector filled with all odd numbers in data int *odds = fvec(sizeof(int)); fvec_filter(data, &odds, is_odd); // print the vectors fvec_print(data, print); fvec_print(odds, print); // free the data behind the vectors fvec_free(&data); fvec_free(&odds); return 0; }
Example without automatic reallocations:
#include <stdio.h> #define FVEC_IMPLEMENTATION #define FVEC_NO_RESIZE #include "fvec.h" #undef FVEC_IMPLEMENTATION int main(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^n int *data = fvecci(sizeof(int), 60); // capacity will be set to 64 // fill vector for(int i = 0; i < fvec_capacity(data); ++i) *(int*)fvec_push(&data) = i; // remove back half of the elements; need to shrink uneccessary allocation for(int i = 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 length fvec_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); return 0; }
Run with make