89 lines
2.1 KiB
C
89 lines
2.1 KiB
C
/* Philip Thrasher's Crazy Awesome Ring Buffer Macros!
|
|
*
|
|
* Below you will find some naughty macros for easy owning and manipulating
|
|
* generic ring buffers. Yes, they are slightly evil in readability, but they
|
|
* are really fast, and they work great.
|
|
*
|
|
* Example usage:
|
|
*
|
|
* #include <stdio.h>
|
|
*
|
|
* // So we can use this in any method, this gives us a typedef
|
|
* // named 'intBuffer'.
|
|
* ringBuffer_typedef(int, intBuffer);
|
|
*
|
|
* int main() {
|
|
* // Declare vars.
|
|
* intBuffer myBuffer;
|
|
*
|
|
* bufferInit(myBuffer,1024,int);
|
|
*
|
|
* // We must have the pointer. All of the macros deal with the pointer.
|
|
* // (except for init.)
|
|
* intBuffer* myBuffer_ptr;
|
|
* myBuffer_ptr = &myBuffer;
|
|
*
|
|
* // Write two values.
|
|
* bufferWrite(myBuffer_ptr,37);
|
|
* bufferWrite(myBuffer_ptr,72);
|
|
*
|
|
* // Read a value into a local variable.
|
|
* int first;
|
|
* bufferRead(myBuffer_ptr,first);
|
|
* assert(first == 37); // true
|
|
*
|
|
* int second;
|
|
* bufferRead(myBuffer_ptr,second);
|
|
* assert(second == 72); // true
|
|
*
|
|
* return 0;
|
|
* }
|
|
*
|
|
*/
|
|
|
|
|
|
#ifndef _ringbuffer_h
|
|
#define _ringbuffer_h
|
|
|
|
int __mod(int a, int b)
|
|
{
|
|
int r = a % b;
|
|
return r < 0 ? r + b : r;
|
|
}
|
|
|
|
#define ringBuffer_typedef(T, NAME) \
|
|
typedef struct { \
|
|
int size; \
|
|
int start; \
|
|
int end; \
|
|
T* elems; \
|
|
} NAME
|
|
|
|
#define bufferInit(BUF, S, T) \
|
|
BUF.size = S+1; \
|
|
BUF.start = 0; \
|
|
BUF.end = 0; \
|
|
BUF.elems = (T*)calloc(BUF.size, sizeof(T))
|
|
|
|
|
|
#define bufferDestroy(BUF) free(BUF->elems)
|
|
#define nextStartIndex(BUF) ((BUF->start + 1) % BUF->size)
|
|
#define nextEndIndex(BUF) ((BUF->end + 1) % BUF->size)
|
|
#define isBufferEmpty(BUF) (BUF->end == BUF->start)
|
|
#define isBufferFull(BUF) (nextEndIndex(BUF) == BUF->start)
|
|
#define bufferGet(BUF, INDEX) (BUF->elems[__mod(BUF->end - INDEX, BUF->size)])
|
|
|
|
#define bufferWrite(BUF, ELEM) \
|
|
BUF->elems[BUF->end] = ELEM; \
|
|
BUF->end = (BUF->end + 1) % BUF->size; \
|
|
if (isBufferEmpty(BUF)) { \
|
|
BUF->start = nextStartIndex(BUF); \
|
|
}
|
|
|
|
#define bufferRead(BUF, ELEM) \
|
|
ELEM = BUF->elems[BUF->start]; \
|
|
BUF->start = nextStartIndex(BUF);
|
|
|
|
#endif
|
|
|