#ifndef RINGBUFFER_H #define RINGBUFFER_H #include // Data layout: ↓head // buffer = [ 4, undef, undef, 1, 2, 3 ] // where 1 is the oldest element and 4 the newest. // Enqueue adds the element after 4 and dequeue removes 1. struct ringbuffer { int head; int size; void (*destroy_element)(void*); int buffer_n; void** buffer; }; /** * Allocate memory and initialize a circular queue with given capacity * * A ringbuffer, or circular queue, is like a regular queue, but if it's full when you add an * element, it displaces the oldest element to make place. As such, adding elements never fails. * * Memory: this function allocates memory for the queue (free it with rbfr_destroy). The * destroy_element function user has to provide must free an element's memory. * * @param capacity maximum amount of elements to accept without dropping oldest * @param destroy_element function called when the queue has to drop an element, with the element * passed as argument * @return pointer to ringbuffer */ struct ringbuffer* rbfr_create(const int capacity, void (*destroy_element)(void*)); /** * Free the queue's memory * * Memory: all elements still present are freed using the destroy_element function provided by user * in rbfr_create. */ void rbfr_destroy(struct ringbuffer* this); int rbfr_size(const struct ringbuffer* this); int rbfr_capacity(const struct ringbuffer* this); /** * Add one element at the end * * If the queue is full (if size==capacity), the oldest element is removed to make place. As such, * this operation does not fail if the queue is full. * * Memory: if an element has to be removed to make place, it is freed using the destroy_element * function provided by user in rbfr_create. */ void rbfr_enqueue(struct ringbuffer* this, void* element); /** * Return first element without removing it from the buffer * * Memory: do not free the element's memory, it still lives in the ringbuffer. */ bool rbfr_peek(const struct ringbuffer* this, void** element); /** * Remove first element and return it * * Memory: user is responsible for freeing the element's memory. */ bool rbfr_dequeue(struct ringbuffer* this, void** element); /** * Remove all elements * * Memory: this function destroys elements using the destroy_element function provided by user in * rbfr_create. */ void rbfr_clear(struct ringbuffer* this); #endif // RINGBUFFER_H