Skip to content

Dynamically sized vector/array in C implemented using fat pointers

License

Notifications You must be signed in to change notification settings

WalkerRout/fvec

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

70 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fvec

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

About

Dynamically sized vector/array in C implemented using fat pointers

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published