/cvec

A generic vector implementation in C

Primary LanguageCGNU General Public License v2.0GPL-2.0

cvec

A generic vector implementation in C (mis)using macros to create strongly typed containers.

Simple example:

#include "vector.h"

VEC_DECLARE_LOCAL(ivec, int)

int main(void)
{
  struct ivec *v = ivec_create();

  for (int i = 0; i < 20; i++)
      ivec_push(v, i);

  printf("Last element is: %d\n", ivec_top(v));

  VFOR(i, v)
      printf("element: %d\n", *i);

  return 0;
}

interface of your custom vector

For this we're gonna assume you called it like VEC_DECLARE_LOCAL(ivec, int)

void    ivec_init(ivec_t *v);                         initialise a stack allocated struct
void    ivec_destroy(ivec_t *v)                       destroys stack allocated struct

ivec_t *ivec_create();                                alloc and initialise a struct on heap
void    ivec_free(ivec_t *v)                          destroys and frees allocated struct from heap

ivec_t *ivec_push(ivec_t *v, int i)                   add one element
int     ivec_pop(ivec_t *v)                           pop one element
int     ivec_top(ivec_t *v)                           get the last element
ivec_t *ivec_extend(ivec_t *v, int *arr, size_t size) add size elements

You can also check it's internals directly for size and access to elements
of your struct ivec. (aliased to ivec_t)

struct ivec
{
   int    *elements;
   size_t  size;
   size_t  capacity;
};

when to use what macro

I had 2 use cases, quick usage, you just need a vector somewhere in a c file:

/* magic to declare and implement vector operations */

void method()
{
  struct integer_vector v;
  integer_vector_init(&v);

  ...
}

Or you want a vector in your own objects with headers etc.

header:

/* magic to just declare vec type and interface */

struct object
{
  vec_object_pointers_t linked_to;
  vec_object_pointers_t objects_linked_to_this;
}
#include header
/* magic to generate implementation */

...

Ideally you'd want to both be able to declare a quick static implementation if you won't reuse it, and a another one if you want more proper usage.

For this there are 3 variants:

VEC_DECLARE_LOCAL, generates the struct and the methods as static.
VEC_DECLARE_HEADER, generates the struct and function prototypes.
VEC_DECLARE_IMPL, generates just the implementation.